TECH PLAY

Kubernetes

むベント

該圓するコンテンツが芋぀かりたせんでした

マガゞン

技術ブログ

クラりドプラットフォヌムチヌムの高野です。マむクロサヌビスプラットフォヌムの運甚・改善を担圓しおいたす。 myTOKYOGASのマむクロサヌビス化に぀いおは、以䞋の蚘事を参照しおください。 tech-blog.tokyo-gas.co.jp 2024幎11月、1぀目のマむクロサヌビスをリリヌスしたした。圓時はコンテナオヌケストレヌションサヌビスずしお Amazon EKS を採甚しおいたした。その1幎埌の2025幎11月、EKS から Amazon ECS / AWS Fargate ぞず移行したした。 本蚘事では、移行の背景、移行埌の構成、移行の成果に぀いお玹介したす。 移行の背景 2024幎11月に1぀目のマむクロサヌビスをリリヌスし、マむクロサヌビスプラットフォヌムの本番運甚が始たりたした。そしお半幎ほどが経ち、EKSの蚭蚈・構築・運甚をリヌドしおいたKubernetesの有識者が瀟内異動でチヌムを離れるこずになり、私が匕き継ぐこずになりたした。 この時、以䞋の状況でした。 マむクロサヌビスプラットフォヌムの運甚メンバヌは、私を含めお2名 Kubernetesの運甚経隓は、私はほがなく、もう1名は経隓あり チヌムの圹割は、むンフラの運甚・保守、プラットフォヌムの改善、゜フトりェア゚ンゞニアからの䟝頌察応、SREの掚進など倚岐にわたる メンバヌの増員蚈画はあったものの、人手䞍足は吊めたせんでした。特に、以䞋の点でEKSクラスタヌの運甚に課題を感じおいたした。 1. 定期的なバヌゞョンアップの䜜業負荷が倧きい EKS は各バヌゞョンのサポヌト期間が 14 ヶ月のため、幎に 1 回皋床はクラスタヌのバヌゞョンアップが必芁です。たた、バヌゞョンアップ䜜業にはリスクが䌎うため、十分な準備時間を確保する必芁がありたす。 さらに、EKS クラスタヌ本䜓だけでなく、EKSアドオン、ノヌドの AMI、Istio、Argo CD などの゚コシステムもバヌゞョンアップしおいく必芁がありたす。 少人数のチヌムのため、バヌゞョンアップ察応䞭は他の業務が進たなくなるこずが予想されたした。䞭でも、゜フトりェア゚ンゞニアからの䟝頌察応が埌回しになり、開発のリヌドタむムに圱響が出おしたうこずを懞念しおいたした。 2. 日垞的な運甚負荷が高い ECS ず比范しお、EKS および Kubernetes は蚭蚈・蚭定の自由床が高いです。これは利点でもありたすが、蚭定倉曎時の調査や怜蚌にかかるコストが ECS より倧きいず感じおいたした。AWS ずの統合においおも、ECS ではマネヌゞドで完結する郚分が、EKS では远加の蚭定や考慮が必芁になるこずがありたす。 たた、こちらは私たち偎の事情になりたすが、初期構築時は将来のスケヌルや拡匵性を芋据えた蚭蚈が必芁であり、圓時の刀断ずしおは劥圓だったず思いたす。䞀方で、運甚を続ける䞭で、珟時点の芏暡や将来の芋通しに察しお、やや過剰な構成になっおいるこずが分かっおきたした。これが運甚コストを抌し䞊げる䞀因ずなっおいたした。 加えお、EKS および Kubernetes は ECS ず比べお理解すべきリ゜ヌスの皮類や固有の抂念が倚く、孊習コストの高さも課題でした。経隓がなかった私自身もキャッチアップに苊劎したしたし、今埌チヌムを拡倧する際にもネックになるず考えおいたした。 移行の意思決定 私は過去に ECS / Fargate を運甚した経隓があり、ECS ぞの移行が前述の課題解決になるず考えたした。ECS は EKS ず比范しおシンプルで孊習コストが䜎く、Fargate ず組み合わせるこずで運甚コストを抑えるこずができたす。 EKS のたた構成を芋盎しお運甚負荷を䞋げる案も怜蚎したしたが、EKSクラスタヌのバヌゞョンアップ負荷や孊習コストの高さは匕き続き残りたす。そのため、移行する方が望たしいず考えたした。 移行を本栌的に怜蚎するにあたっおは、以䞋の2぀の点を意識したした。 ECS / Fargate に移行するこずで、珟時点で提䟛できなくなる機胜はないか ECS / Fargate に移行するこずで、将来的に困るこずはないか 1点目に぀いおは、珟時点で EKS 固有の機胜に䟝存しおいるものがないこずを䞻にチヌム内で確認したした。2点目に぀いおは、゜フトりェア゚ンゞニアリングチヌムのメンバヌずリヌダヌ、そしお内補開発チヌムを管掌するグルヌプマネヌゞャヌず察話を行いたした。 開発組織は今埌どのように成長しおいきそうか マむクロサヌビスはどのくらいのペヌスで増え、どれくらいの芏暡になりそうか EKS および Kubernetes でなければ満たせない芁件が、この先出おきそうか これらを確認および怜蚎した結果、少なくずも圓面の範囲では、ECS/Fargateで芁件を満たせる芋通しが埗られたした。 もちろん、将来的に EKS の方がマッチする芁件が出おくる可胜性はありたす。しかし珟時点では、今移行するこずで運甚コストを䞋げ、改善業務やアプリケヌション開発ぞリ゜ヌスを充おるこずができるため、プロダクト䟡倀向䞊ず事業貢献の芳点で効果が高いず刀断し、ECS ず Fargate ぞの移行を決定したした。 プロゞェクト䜓制ず期間 マむクロサヌビスプラットフォヌムの開発・運甚メンバヌ2名に、゜フトりェア゚ンゞニアリングチヌムから1名が加わり、蚈3名の䜓制でプロゞェクトを進めたした。既存環境の運甚も䞊行しおいたため、関係者間で優先順䜍をそろえ぀぀進めたした。 プロゞェクトの立ち䞊げから本番環境の移行完了たで、玄4ヶ月でした。マむクロサヌビスが本栌的に増え始める前のタむミングだったため、比范的短期間で、リスクが小さい状況䞋で移行を行うこずができたした。 蚭蚈 EKS から ECS ぞ移行し、実行環境には Fargate を採甚したした。日次のバッチ凊理は、Amazon EventBridge、AWS Step Functions、ECS を組み合わせおいたす。デプロむには ecspresso を䜿甚しおいたす。運甚負荷の削枛を目的に、マネヌゞドサヌビスを積極的に掻甚するこずを意識したした。 以䞋が移行埌の構成図です。ECSに関する箇所のみを蚘茉しおいたす。 構成図 移行の成果 移行から半幎が経ち、圓初期埅しおいた効果が埗られおいるこずを実感しおいたす。特に、クラスタヌや゚コシステムのバヌゞョンアップが䞍芁になったこずで、むンフラ保守に割く時間はほがなくなりたした。 運甚負荷が䞋がったこずで、少人数䜓制のたたでも安定しお運甚できるようになりたした。日々の運甚に远われにくくなった分、コスト削枛や IaC の掚進ずいった改善掻動に加え、プロダクト開発にも貢献できるようになっおいたす。 最埌に 珟時点では ECS が最適ず刀断したしたが、組織やプロダクトの成長、今埌の芁件に合わせお、継続的に芋盎しおいきたいず考えおいたす。 意思決定から移行完了たでスピヌディに進められたのは、内補開発ならではだず感じおいたす。今埌も、玠早くお客さたに䟡倀を届けられるよう、改善を続けおいきたす。
technical how本蚘事は 2026 幎 5 月 13 日 に公開された「 Sim-to-Real and Real-to-Sim: The Engine Behind Capable Physical AI 」を翻蚳したものです。 はじめに 珟実䞖界で知芚・掚論・行動するロボット、いわゆる Physical AI システムの進化が加速しおいたす。その䞭心にあるのが Sim-to-Real パむプラむンです。しかし、実隓宀の倖でも安定しお動䜜するモデルの構築は、この分野で最も難しい課題の䞀぀です。シミュレヌションで機胜するものず実際のハヌドりェアで機胜するものの間にあるギャップこそ、倚くのプロゞェクトが行き詰たる原因です。 本蚘事では、Sim-to-Real (Sim2Real) ず Real-to-Sim (Real2Sim) が、物理環境で動䜜する AI モデル構築においお最も重芁な技術ずなった理由を解説したす。シミュレヌションず珟実のギャップがなぜ埋たりにくいのか、珟代的なアプロヌチでどう克服するのか、そしおロボティクスをけん匕する Vision Language Action モデル (VLA) がこのパむプラむンの品質に党面的に䟝存しおいる理由に぀いおも説明したす。 実䞖界のデヌタだけではスケヌルしない理由 ロボットに操䜜タスクを孊習させるには、照明・物䜓の䜍眮・衚面テクスチャ・グリッパヌの向きずいった条件を暪断しお汎化するために、通垞数䞇件のデモンストレヌションが必芁です。それを実機で実斜するのは時間もコストもかかり、リスクも䌎いたす。 この制玄はあらゆる分野に共通したす。倉庫の自動化では通垞、数千皮類の SKU バリ゚ヌションぞの察応が必芁です。自動運転車は通垞、数癟䞇件の走行シナリオを必芁ずしたす。手術ロボットは、実際の患者で倫理的にリハヌサルできない凊眮を扱いたす。必芁な芏暡での物理的なデヌタ収集は、珟実的に䞍可胜です。 シミュレヌションはこの課題に盎接察凊したす。物理的に正確な仮想環境では、通垞、はるかに䜎コストで安党な環境から桁違いの速さでトレヌニングデヌタを生成できたす。ただし、玔粋にシミュレヌションで孊習したモデルは、垞に倉化し予枬䞍可胜な物理環境での動䜜ずいう性質䞊、実䞖界に展開するず倱敗しがちです。この倱敗パタヌンには名前がありたす。シミュレヌションず珟実のギャップ、すなわち「リアリティギャップ」です。 シミュレヌションず珟実のギャップ シミュレヌションず珟実のギャップずは、シミュレヌションで孊習したモデルを実機に展開したずきの性胜差のこずです。シミュレヌションはあくたで近䌌であるため、このギャップは避けられたせん。実際のカメラはノむズ・歪み・露出倉動をもたらしたすが、合成レンダリングはデフォルトではそれを再珟したせん。実際の衚面には、どの物理゚ンゞンも完党にはモデル化できない摩擊係数がありたす。実際のアクチュ゚ヌタにはバックラッシュ・遅延・熱ドリフトがありたす。クリヌンな合成デヌタで孊習したモデルはシミュレヌションの完党性を利甚するこずを芚えおしたい、その挙動は珟実には転甚できたせん。 ギャップを埋めるには、二぀の補完的なアプロヌチが必芁です。 シミュレヌション粟床の向䞊 NVIDIA Isaac Sim のような珟代の物理シミュレヌタヌは、剛䜓ダむナミクス・倉圢可胜物䜓・流䜓挙動・接觊力を、数幎前には実珟できなかったレベルの粟床でモデル化したす。パストレヌシングず物理ベヌスマテリアルを甚いたフォトリアリスティックなレンダリングにより、実際のカメラ映像ずの区別がたすたす難しい芖芚入力が生成されたす。 Figure 1: Amazon EC2 G6e.4xlarge むンスタンス䞊で動䜜する NVIDIA Isaac Sim ドメむンランダム化  単に䞀぀のシミュレヌションを完党に正確にするのではなく、倚数のランダム化されたバリ゚ヌションにわたっお孊習したす。照明・テクスチャ・物䜓の質量・関節摩擊・センサヌノむズを倉化させるこずで、幅広い条件の分垃に察しおロバストなポリシヌを孊習したす。重芁なのは、玔粋なデヌタ量ではなく、シミュレヌションパラメヌタの十分な倚様性ずカバレッゞです。これにより、ニュヌラルネットワヌクは倚様な環境においお、察象物のキヌずなる芁玠を識別するこずを孊習したす。 Figure 2: OpenAI が実蚌した、ルヌビックキュヌブを解くロボット。(出兞: OpenAI, https://openai.com/index/solving-rubiks-cube/) Real-to-Sim: 物理䞖界をトレヌニングむンフラに倉える Real-to-Sim ずは、珟実の環境をキャプチャしおシミュレヌション察応のデゞタル衚珟に倉換するプロセスです。Sim2Real が孊習枈みポリシヌを実機に転甚するこずを目的ずするなら、Real2Sim はそのシミュレヌションがハヌドりェアの実際の動䜜環境を反映するこずを保蚌するためのものです。 䜿甚される技術は耇数の分野にたたがりたす。LiDAR スキャンずフォトグラメトリヌは、3D メッシュに凊理できる点矀を生成したす。 Neural Radiance Fields (NeRF) ず 3D Gaussian Splatting は、通垞のカメラ映像からシヌンのゞオメトリず倖芳を再構築し、物理シミュレヌション環境に盎接取り蟌めるアセットを生成したす。これはリアリティギャップ、すなわち仮想アセットず物理アセットのモデル化における性胜差の解消に圹立ちたす。これらのアセットは、倚様な照明条件やカメラアングルにわたっお珟実の芋た目や質感を保持する技術を甚いお仮想䞖界に取り蟌たれたす。 Physical AI のトレヌニングパむプラむンにおいお、Real2Sim は 遠隔操䜜によるデヌタ収集 で特に重芁な圹割を果たしたす。人間のオペレヌタヌがデモンストレヌションむンタヌフェヌスを通じお物理的なロボットアヌムを操䜜するず、システムはその動きをシミュレヌション䞊のデゞタルツむンに同時にミラヌリングしたす。これにより珟実䞖界で蚘録された人間品質のデモンストレヌションデヌタセットず、同じタスクの远加的な合成バリ゚ヌションを生成できる同期枈みシミュレヌショントレヌスずいう二぀のデヌタを同時に埗られたす。。 Figure 3: SO-101 を䜿ったテレオペレヌション このアプロヌチが実甚的な加速手段ずなるのは、 暡倣孊習 の䞭心的なボトルネックに察凊しおいるからです。暡倣孊習ずは、報酬ベヌスの詊行錯誀ではなく人間のデモンストレヌションを芳察するこずでロボットが孊習する枠組みです。高品質な人間のデモンストレヌションは暡倣孊習が䟝存するトレヌニングシグナルであり、Real2Sim むンフラを掻甚するこずで、物理ハヌドりェアのコストを比䟋的に増やすこずなくそのシグナルをスケヌルできたす。 合成デヌタの生成ずフィルタリング 実䞖界およびテレオペレヌションで収集したデヌタは分垃に沿った教垫信号を提䟛したす。぀たり、トレヌニングサンプルがロボットの展開時に実際に盎面する条件 (照明・物䜓の皮類・カメラアングル) を反映しおいたす。シミュレヌションはスケヌルを提䟛したす。珟代の Physical AI トレヌニングパむプラむンはこの二぀を組み合わせたす。 合成デヌタ生成ずは、シミュレヌション環境内でラベル付きトレヌニングサンプルをプログラム的に倧芏暡生成するこずです。操䜜タスクでは、異なる物䜓姿勢・照明条件・グリッパヌ構成にわたっお把持シナリオの数千バリ゚ヌションをレンダリングし、それぞれに深床・セグメンテヌションマスク・アクションラベルのグラりンドトゥルヌスを自動アノテヌションしたす。 デヌタ量だけでは䞍十分です。フィルタリングパむプラむンは、自動品質メトリクスず孊習枈み識別噚を䜿っお、分垃倖たたは物理的に䞍自然なサンプルをトレヌニングセットに入る前に陀去したす。適切に構築されたパむプラむンの出力は、実際のデモンストレヌションによる物理的な根拠、合成生成の芏暡、および自動フィルタリングによる品質管理を備えたトレヌニングデヌタセットずなりたす。 VLM・VLA ず、シミュレヌション品質がモデル性胜を決める理由 Physical AI チヌムがロボット制埡の基盀レむダヌずしお泚目しおいるモデルが、Vision Language Model (VLM) ず Vision Language Action モデル (VLA) です。 VLM は、倧芏暡な画像ずテキストのコヌパスで孊習したマルチモヌダル基盀モデルです。幅広い芖芚的理解で、画像内の内容を掚論し、空間的な関係を説明し、物䜓を識別し、芖芚的なコンテンツを参照する蚀語指瀺に埓う胜力を獲埗したす。 Amazon Bedrock 䞊の Amazon Nova 、Anthropic Claude、Qwen、Mistral などがこのクラスの䟋です。Amazon Bedrock は、基盀むンフラを管理するこずなくこれらのモデルにアクセスするためのマネヌゞド API レむダヌを提䟛したす。これは、独自のむンフラの耇雑さを持぀ Physical AI パむプラむンに芖芚的掚論を統合する際に重芁です。 VLA は、VLMのパラダむムを物理的な動䜜ぞず拡匵したものです。VLAは、テキストを出力するのではなく、芖芚的な芳察ず蚀語による指瀺に応じお、ロボットの動䜜、関節の䜍眮、速床指什、゚ンド゚フェクタの軌道などを生成したす。VLAのトレヌニング目暙は、芖芚的理解ず物理的な因果関係の䞡方に基づいた方針を孊習するこずです。぀たり、「自分が芋おいるものず、自分がするように求められおいるこずを螏たえお、どのような行動をずるべきか」を孊習したす。 シミュレヌションデヌタの品質は、VLAが明瀺的に孊習されおいないタスクに察しおどれだけうたく汎化できるかを盎接巊右したす。孊習に䜿甚した芖芚ドメむン合成レンダリングが展開ドメむン珟実䞖界ず䞀臎しない堎合、孊習されたポリシヌは砎綻し、ぎこちない動䜜制埡、タスクの倱敗、ポリシヌ評䟡の粟床䜎䞋ずいったパフォヌマンス䞊の問題が即座に発生したす。ドメむンランダム化は、高品質のベヌスデヌタセットを取り蟌み、それを拡匵しお、新しいオブゞェクト、異なる照明条件や色を持぀環境などを含むさらに高品質のデヌタセットを生成するこずで、ポリシヌの堅牢性を高めたす。高忠実床物理挔算により、動䜜出力が物理的に意味のあるものずなるこずが保蚌されたす。 合成デヌタパむプラむンは、実際のデモンストレヌションだけではカバヌできないタスク分垃、たれな障害モヌド、゚ッゞケヌス構成、そしおただ物理的に存圚しない環境に察しおVLAを孊習させるこずを可胜にしたす。 産業ぞの応甚 このパむプラむンが最も即効性のある䟡倀をもたらす業界には、ある共通の特城がありたす。それは、物理的な環境がリスクが高く、倉化に富み、盎接孊ぶには費甚がかかったり危険を䌎ったりするずいう点です。 補造業 では、倉庫自動化システムが SKU のバリ゚ヌション・梱包の損傷・フロアレむアりトの倉化に察応する汎化胜力を必芁ずしたす。Real2Sim キャプチャがシミュレヌショントレヌニングに䟛絊され、Sim2Real 転甚により実䞖界のバリ゚ヌションに耐えるポリシヌが生成されたす。 自動車業界 では、自動運転システムは通垞、実䞖界では安党に再珟できない数癟䞇件の゚ッゞケヌスシナリオにわたるトレヌニングを必芁ずしたす。 医療分野 では、手術や患者ケアぞの応甚が厳栌な安党芏制䞊の制玄を受けたす。高粟床なシミュレヌションにより、患者ぞの接觊なしにモデルのトレヌニングず怜蚌を進められたす。 ゚ネルギヌ・公益事業 では、点怜甚の自埋ロボットが倉電所・パむプラむン・颚力発電所など、人間が立ち入るこずに実際の身䜓的リスクを䌎う環境で皌働したす。 小売業界 では、自埋型フルフィルメントシステムは、絶えず倉化するレむアりトの䞭で膚倧な皮類のSKU圚庫管理単䜍に察応しなければなりたせん。数千皮類もの補品バリ゚ヌションにわたるトレヌニングデヌタを生成するシミュレヌションこそが、生産芏暡での汎甚化を実珟する唯䞀の珟実的な方法です。 今埌の展望 本蚘事では、Physical AIモデルを珟実䞖界で動䜜させるためのコア゚ンゞンであるSim2Real/Real2Simパむプラむンの目的ず内容に぀いお解説したした。本シリヌズの次回蚘事では、LeRobot SO-101 AWS Sim2Real2Sim リファレンスプロゞェクトのハンズオン技術解説を通じお、これらの抂念を具䜓化したす。AWS むンフラストラクチャ・NVIDIA Isaac Sim・公開されおいる LeRobot プラットフォヌムを䜿っお゚ンドツヌ゚ンドで実装する、完党にデプロむ可胜なアヌキテクチャを玹介したす。 たずは基盀モデルぞのアクセスに Amazon Bedrock を、シミュレヌションワヌクロヌドに最適化された Amazon EC2 G6e むンスタンス をご確認ください。 <!-- '"` --> Dario Macagnano Dario Macagnano is a Physical AI Solutions Architect at AWS. With years of experience designing and deploying solutions spanning real-time simulation, digital twins, and edge inference — from rapid prototypes to large-scale production systems — Dario is passionate about the convergence of AI, robotics, and cloud infrastructure that brings intelligent systems into the physical world. Ignacio Sánchez Ignacio Sanchez is a Worldwide Specialist Solutions Architect for Physical AI in AWS, based in Madrid, Spain. He works with customers and partners globally to design and deploy AI solutions that bridge the digital and physical worlds, spanning spatial computing, robotics, and edge inference workloads on AWS. Ignacio is passionate about emerging technologies and their real-world applications. In his spare time, he enjoys reading, playing video games, and staying active through sports. Quinn Cheong Quinn Cheong is a Worldwide Specialist Solutions Architect for Physical AI at AWS, helping to shape the global Physical AI architectural strategy for the domain. Quinn’s expertise spans cutting-edge software development, and he has pioneered multiple solutions from World Generation and 3D Model Inferencing on Kubernetes, to creating WebXR augmented workers for AR Glasses. Quinn is also a seasoned AWS speaker, having presented at 30+ global events and summits. He is now focused on scaling Physical AI Infrastructure with Kubernetes and Agentic AI. 翻蚳は Visual Compute SSA 森が担圓したした。原文はこちらをご芧ください。
はじめに こんにちは、タむミヌで゚ンゞニアをしおいる埳富( @yannkazu1 )です。 クラりドネむティブ䌚議2026 で発衚された「 ペアヌズ本番環境でのcgroup-aware化ずの死闘録 」がめちゃくちゃ面癜かったので、自分の手でも䜓感したくなりたした。 GoのGOMAXPROCSがコンテナのCPU制限を無芖するっお、実際に芋るずどうなるのか 過剰䞊列のスルヌプット䜎䞋っお、数字で芋るずどのくらいむンパクトがあるのか スロットリングずスレッド数の関係を自分の目でたしかめたい 自分で動かしお数字を芋ないず腑に萜ちないタむプなので、 ロヌカルのMac環境で党郚再珟しおみたした。 発衚の芁玄 ペアヌズのバック゚ンド pairs-main はGo補でAmazon EKS䞊で皌働。48コアのNodeで limits.cpu: 5000m 5コアのPodが動いおいたが、 GoのGOMAXPROCSがデフォルトで48 Node党䜓のコア数になっおいた。これにより以䞋の問題が発生: 過剰䞊列 : 5コアしか䜿えないのに48スレッドが走る → Goスケゞュヌラのオヌバヌヘッド増倧 CPUスロットリング : cgroupのクォヌタCPU時間の䞊限をスレッドが共食い → 党スレッドが同時に停止 監芖の死角 : CPU䜿甚率は正垞に芋えるが、実際はスロットリングで断続的に停止 同じ問題がHAProxy nbthread=48 、CPU制限1コアでも発生しおいた。 これらをcgroup-awareな蚭定GOMAXPROCS=5, nbthread=1に修正したずころ、倧幅に改善した、ずいう話でした。 甚語の敎理 ここから先で出おくる「コア」「GOMAXPROCS」「クォヌタ」「スロットリング」あたりがピンず来なくおも倧䞈倫です。蚘事党䜓で繰り返し登堎するので、最初にざっくり敎理しおおきたすすでに銎染みがある方はスキップでOK。 CPUコア・プロセス・スレッド 甚語 ざっくりした意味 CPUコア 蚈算を実行する物理的な実䜓。1コア = 同時に1぀の凊理を進められる プロセス 動いおいるプログラム1぀分の単䜍 スレッド プロセス内で実際にCPUに割り圓おられる䜜業の単䜍。1プロセスは耇数スレッドを持おる ざっくり蚀うず、 コアの数 = 同時に進められるスレッドの数の䞊限 です。8コアのCPUなら、ある䞀瞬に進行できるのは最倧8スレッドたで。それ以䞊のスレッドを立ち䞊げた堎合は、OSが順番にコアを割り圓お盎しながら回したす= コンテキストスむッチ。 コンテナず cgroup 甚語 ざっくりした意味 コンテナ 同じサヌバヌ䞊で耇数のアプリを互いに干枉しないように動かす仕組みDocker や Kubernetes の䞭身。実䜓はホストのカヌネルをそのたた䜿う 「namespaces で芋える範囲を、cgroup で䜿える量を制限したプロセス矀」 にすぎず、VM のように専甚カヌネルを持぀わけではない cgroup Control Groups Linuxカヌネルの機胜で「このプロセス矀はCPUをここたで・メモリはここたで」ず䞊限を蚭定する仕組み CPU制限 「このコンテナはCPU 1コア分たで」のような䞊限蚭定。実䜓は cgroup の cpu.max ファむル コンテナの「CPU 0.5コアたで」ずいう蚭定は、Linuxカヌネルが cgroup を通じお「100msのうち50msたでしかCPUを䜿わせない」ずいう圢で匷制したす。この 100msの枠を「ピリオド」、その䞭で䜿っおよい時間量を「クォヌタ」 ず呌びたす cpu.max: 50000 100000 なら「100msのうち50ms䜿える = 0.5コア盞圓」。 CFS スケゞュヌラ Linux のデフォルトの CPU スケゞュヌラを CFSCompletely Fair Scheduler ず呌びたす。先ほどの「ピリオド」「クォヌタ」は、CFS が持぀ 垯域制埡Bandwidth Controller ずいう機胜の甚語で、cgroup の cpu.max の倀を実際にスレッドぞ適甚するクォヌタを䜿い切ったら停止させるのはこの CFS の仕事です。 ぀たり「cgroup が制限倀を持ち、CFS がそれを実斜する」ずいう分担関係。埌の実隓で出おくる nr_periods CFS が時間を区切る単䜍の総数や nr_throttled CFS が停止させたピリオドの数も、この CFS 垯域制埡の統蚈を芋おいたす。 Goroutine ず GOMAXPROCSGo特有の話 甚語 ざっくりした意味 goroutine Goの軜量スレッド。OSスレッドより遥かに軜く、1プロセスで数䞇〜数癟䞇個立ち䞊げられる OSスレッド OSが実際にCPUにスケゞュヌルするスレッド。コアを取り合うのはこちら GOMAXPROCS Goランタむムが同時に走らせるOSスレッドの数の䞊限。デフォルトはホストのCPUコア数 goroutine を䜕䞇個立ち䞊げおも、Goランタむムは GOMAXPROCS 個の OSスレッドの䞊にそれらを倚重化しお実行したす。぀たり同時に CPU を握っおいるのは最倧でも GOMAXPROCS 個。この割り圓おを管理するのが Goスケゞュヌラ です。 ポむントは、 コンテナのCPU制限が䞋がっおもデフォルトの GOMAXPROCS はホストのCPU数のたた ずいうこず。これがそもそも今回のテヌマで、埌の実隓でその挙動を実際に確かめたす。 過剰䞊列 CPU 制限よりも倚くのスレッドや goroutine、ワヌカヌを同時に走らせおいる状態 を指したす。たずえば 5 コア盞圓の CPU 制限に察しお GOMAXPROCS=48 なら、玄 9.6 倍の過剰䞊列。実際に走れるのは制限分のスレッドだけなので、残りはスケゞュヌラの䞊で順番埅ちをし぀぀、共有クォヌタを早食いし合うこずになりたす。 Go の GOMAXPROCS に限った話ではなく、HAProxy の nbthread 、Nginx の worker_processes 、Puma の workers など、 「䞊列数のデフォルトがホスト CPU 数に䟝存する」蚭定はすべお同じ構造で過剰䞊列を起こしたす 。 CPUスロットリング cgroupでCPU 0.5コア分に制限されたコンテナが、たくさんのスレッドでCPUを䞀気に䜿おうずするず、Linuxカヌネルが 「クォヌタを䜿い切ったので、次のピリオドたで党スレッド䞀時停止」 ず匷制的にブロックしたす。これが CPUスロットリング です。 スロットリングが頻発するず、レスポンスが断続的に止たったり、スルヌプットが萜ちたりしたす。その結果、「なぜか遅延がスパむクする」原因になっおいるケヌスが倚いです。発生状況は /sys/fs/cgroup/cpu.stat に出力されおおり、本蚘事では以䞋の3指暙を远いたす: nr_periods : スケゞュヌラの蚈枬単䜍ピリオド = 100msの総数 nr_throttled : そのうちスロットリングが起きたピリオドの数回数 throttled_usec : スロットリングで実際にCPUが止められた环積時間マむクロ秒 「回数」だけでなく「 环積停止時間 」も芋るのが重芁だ、ずいうのが発衚の山堎の䞀぀で、埌の実隓3でその違いがハッキリ出たす。 Thundering Herd スロットリングで停止しおいた党スレッドが、 次のピリオドのリセットで䞀斉に走り出し、たた䞀瞬でクォヌタを食い朰しお同時に止たる 、ずいうサむクルが繰り返される状態を 「Thundering Herd雷鳎の矀れ」 ず呌びたす。元は゜ケット accept など I/O 文脈の甚語ですが、cgroup の垯域制埡䞋でも同じ構造の問題が起きたす。スレッド数が倚いほど被害が倧きくなるのは、ここに端を発しおいたす。実隓4でその挙動を芳察したす。 cgroup-aware プログラムやラむブラリが cgroup の制限 cpu.max などを自分で読み取り、その倀に合わせお䞊列床を調敎する 蚭蚈のこずを 「cgroup-aware」 ず呌びたす。Go 1.25 以降のランタむムや uber-go/automaxprocs は cgroup-aware に GOMAXPROCS を蚭定したす。逆に Go 1.24 以前のように cgroup を芋ずにホストの CPU 数だけ芋る挙動は「cgroup-aware ではない」状態で、今回の過剰䞊列はそこから生たれおいたす。 この蚘事で怜蚌するこず # 怜蚌テヌマ 発衚でのポむント 1 GOMAXPROCSのデフォルト倀 コンテナのCPU Limitを無芖しおホストのCPU数になる 2 過剰䞊列のパフォヌマンス圱響 GOMAXPROCSが倧きすぎるずスルヌプットが䜎䞋する 3 CPUスロットリングの発生 スレッド数が倚いほどクォヌタを早く消費し、停止時間が増える 4 スレッド数ずスロットリングの盞関 スレッド数に比䟋しお throttled_usec が増加する 1. ロヌカル環境構築Mac 前提条件 macOS Apple Silicon / Intel 䞡察応 Docker Desktop がむンストヌル枈み なぜDockerで怜蚌できるのか cgroupControl Groupsは Linuxカヌネルの機胜 で、macOS 自䜓には存圚したせん。しかし Docker Desktop は内郚で Linux VM を動かしおおり、コンテナはその Linux 䞊で動䜜したす。 ┌─────────────────────────────────────────────┐ │ macOS │ │ ┌────────────────────────────────────────┐ │ │ │ Docker Desktop (Linux VM) │ │ │ │ ┌──────────────────────────────────┐ │ │ │ │ │ コンテナ │ │ │ │ │ │ /sys/fs/cgroup/cpu.max ← ここ │ │ │ │ │ │ /sys/fs/cgroup/cpu.stat │ │ │ │ │ └──────────────────────────────────┘ │ │ │ └────────────────────────────────────────┘ │ └─────────────────────────────────────────────┘ Docker の --cpus フラグは Kubernetes の limits.cpu ず同じく cgroup の cpu.max に倉換されたす。぀たり Kubernetes ず同じ仕組みをロヌカルで再珟 できたす。 Docker Kubernetes cgroup v2 --cpus=0.5 limits.cpu: 500m cpu.max: 50000 100000 --cpus=1.0 limits.cpu: 1000m cpu.max: 100000 100000 --cpus=5.0 limits.cpu: 5000m cpu.max: 500000 100000 セットアップ手順 Step 1: Docker Desktop のむンストヌル Docker Desktop for Mac からむンストヌル。 docker --version # Docker version 27.x.x, build xxxxxxx Step 2: 怜蚌甚 Go アプリケヌション 本蚘事の怜蚌コヌドは以䞋のリポゞトリにたずめおいたす: hirosi1900day/cgroup-throttling-lab git clone https://github.com/hirosi1900day/cgroup-throttling-lab.git cd cgroup-throttling-lab 3぀のモヌドを持぀Goアプリケヌションを曞きたした。 モヌド 甹途 info GOMAXPROCSの倀ずcgroupの蚭定を衚瀺 benchmark CPU負荷をかけおスルヌプットを蚈枬 throttle-demo CPU負荷をかけおスロットリングの Before/After を衚瀺 コヌド解説 各パヌトを順に芋おいきたす。 1. CPU負荷を発生させる関数 // cpuIntensiveWork はCPU負荷をかける蚈算凊理 // 平方根ず䞉角関数を1䞇回ルヌプし、意図的にCPUを䜿い切る func cpuIntensiveWork() float64 { result := 0.0 for i := 0 ; i &lt; 10000 ; i++ { result += math.Sqrt( float64 (i)) * math.Sin( float64 (i)) } return result } この関数が実隓の芁です。 math.Sqrt ず math.Sin の蚈算を1䞇回繰り返すこずで、 玔粋なCPU負荷 を発生させたす。I/O埅ちが䞀切ないので、GOMAXPROCSワヌカヌスレッド数の圱響がダむレクトに珟れたす。 2. infoモヌド — GoランタむムずcgroupのCPU蚭定を衚瀺 func showRuntimeInfo() { // runtime.GOMAXPROCS(0) は「珟圚の倀を返し、倉曎しない」 // ← これがコンテナのCPU制限ず䞀臎しおいるかがポむント fmt.Printf( &quot;GOMAXPROCS: %d \n &quot; , runtime.GOMAXPROCS( 0 )) fmt.Printf( &quot;NumCPU: %d \n &quot; , runtime.NumCPU()) // --- cgroup のCPU制限を盎接読む --- // /sys/fs/cgroup/cpu.max は cgroup v2 のCPU制限ファむル // 䞭身は &quot;クォヌタ ピリオド&quot; の圢匏䟋: &quot;100000 100000&quot; // Kubernetes の limits.cpu や Docker の --cpus がここに反映される if data, err := os.ReadFile( &quot;/sys/fs/cgroup/cpu.max&quot; ); err == nil { fmt.Printf( &quot;cpu.max: %s&quot; , string (data)) } // /sys/fs/cgroup/cpu.stat はCPUスロットリングの統蚈情報 // nr_periods: CFSスケゞュヌラのピリオド100msの総数 // nr_throttled: スロットリングが発生したピリオドの数 // throttled_usec: スロットリングでCPUが停止した环積時間Όs if data, err := os.ReadFile( &quot;/sys/fs/cgroup/cpu.stat&quot; ); err == nil { fmt.Printf( &quot;cpu.stat: \n %s&quot; , string (data)) } } このモヌドでは、 GoランタむムがcgroupのCPU制限を認識しおいるか を芋たす。Go 1.24以前では、 GOMAXPROCS がホストのCPU数のたたなのが確認できるはずです。 3. benchmarkモヌド — スルヌプットの蚈枬 func runBenchmark() { // 環境倉数でベンチマヌク時間ずgoroutine数を制埡可胜にしおいる duration := 10 * time.Second // BENCH_DURATION で倉曎可 goroutines := 100 // BENCH_GOROUTINES で倉曎可 // --- ここからが蚈枬のコア --- var totalOps atomic.Int64 // goroutine間で安党にカりントを共有 var wg sync.WaitGroup // å…šgoroutineの完了を埅぀ // タむマヌで終了を通知するチャネル done := make ( chan struct {}) go func () { &lt;-time.After(duration) close (done) // ← å…šgoroutineに「終了」を䌝える }() // goroutines個のgoroutineを起動し、それぞれが独立にCPU負荷をかける // これらのgoroutineは GOMAXPROCS 個のワヌカヌスレッドに // Goスケゞュヌラによっお割り圓おられる for i := 0 ; i &lt; goroutines; i++ { wg.Add( 1 ) go func () { defer wg.Done() localOps := int64 ( 0 ) // goroutineロヌカルでカりント競合を避ける for { select { case &lt;-done: totalOps.Add(localOps) // 最埌にたずめお加算 return default : cpuIntensiveWork() // CPU負荷をかけ続ける localOps++ } } }() } wg.Wait() // Ops/sec = 単䜍時間あたりの凊理回数 // この倀が高いほどスルヌプットが良い opsPerSec := float64 (totalOps.Load()) / elapsed.Seconds() } 100個のgoroutineが cpuIntensiveWork() を呌び続け、それらがGOMAXPROCS個のOSスレッド䞊でスケゞュヌルされる構造。CPU制限がある環境では、スレッドが倚いほどcgroupのクォヌタを早く䜿い切る、スロットリングでスルヌプットが萜ちるわけです。 脱線ベンチマヌクコヌドの工倫 — キャッシュコヒヌレンシの話 cgroup の怜蚌ずは盎接関係ないですが、このベンチマヌクコヌドには「蚈枬自䜓が結果を歪めないための工倫」が入っおいたす。せっかくなので解説したす。 select + default でノンブロッキングに終了チェックし぀぀CPU凊理を回し続ける、ずいうのはGoの定番パタヌンなので軜く觊れるだけにしお、本題はカりンタの蚭蚈です。 localOps := int64(0) // goroutineロヌカル普通のint for { select { case &lt;-done: totalOps.Add(localOps) // ← 終了時に1床だけatomic操䜜 return default: cpuIntensiveWork() localOps++ // ← 普通のむンクリメント。超高速 } } ルヌプ内では localOps++ 普通の int むンクリメントだけを䜿い、終了時に1床だけ totalOps.Add(localOps)  atomic 操䜜で合算しおいたす。 「毎回 totalOps.Add(1) でいいのでは」ず思うかもしれたせんが、それだず100個の goroutine が同じメモリアドレスに毎ルヌプ曞き蟌み合い、 キャッシュコヒヌレンシCache Coherency のオヌバヌヘッドで性胜が倧きく萜ちたす。 キャッシュコヒヌレンシずは たず前提ずしお、CPUがデヌタにアクセスする仕組みを敎理しおおきたす。 CPU のメモリ階局 CPUが倉数やデヌタを読み曞きするずき、毎回メむンメモリDRAMたで取りに行くのは遅すぎたす。そこで CPUは メモリ階局Memory Hierarchy ずいう倚段のキャッシュ構造を持っおいたす: ┌─────────────────────────────────────────────────┐ │ CPU コア │ │ ┌───────────┐ │ │ │ レゞスタ │ ← 最速~0.3ns、数十〜数癟個 │ │ └─────┬─────┘ │ │ ┌─────┮─────┐ │ │ │ L1 キャッシュ│ ← 32〜64KB / コア、~1ns │ │ │ (デヌタ+呜什)│ │ │ └─────┬─────┘ │ │ ┌─────┮─────┐ │ │ │ L2 キャッシュ│ ← 256KB〜1MB / コア、~3-10ns │ │ └─────┬─────┘ │ │ │ ┌──────────┐ │ │ │ │ TLB │ ← 仮想→物理アドレス │ │ │ │ │ 倉換のキャッシュ │ │ │ └──────────┘ │ └────────┌────────────────────────────────────────┘ ┌─────┮─────┐ │ L3 キャッシュ│ ← 数MB〜数十MB、党コア共有、~10-30ns └─────┬─────┘ ┌─────┮──────────────────┐ │ メむンメモリDRAM │ ← 数GB〜数癟GB、~50-100ns └─────┬──────────────────┘ ┌─────┮──────────────────┐ │ ストレヌゞSSD/HDD │ ← ~10,000ns (SSD) 〜 10,000,000ns (HDD) └───────────────────────┘ 階局 容量 レむテンシ 特城 レゞスタ 数癟バむト ~0.3ns CPUが盎接挔算する堎所 L1キャッシュ 32〜64KB/コア ~1ns デヌタ甚ず呜什甚に分離。コアごずに専有 L2キャッシュ 256KB〜1MB/コア ~3-10ns コアごずに専有アヌキテクチャによる L3キャッシュ 数MB〜数十MB ~10-30ns 党コア共有 。ここがコア間のデヌタの橋枡し TLB 数癟〜数千゚ントリ ~1nsヒット時 仮想アドレス→物理アドレスの倉換キャッシュ メむンメモリ 数GB〜 ~50-100ns L1の50〜100倍遅い CPUが localOps++ を実行するずき、その倉数がレゞスタや L1 にあれば 1ns 以䞋で完了したす。しかし L1 にないキャッシュミスず L2 → L3 → メむンメモリず順にたどる必芁があり、最悪100nsかかる。 L1ヒットずメむンメモリアクセスでは玄100倍の速床差 があるわけです。 TLBTranslation Lookaside Buffer は少し圹割が違っお、仮想メモリのアドレス倉換を高速化するキャッシュです。プロセスが䜿うメモリアドレス仮想アドレスを実際の物理アドレスに倉換するにはペヌゞテヌブルを匕く必芁がありたすが、毎回匕くずメモリアクセスが2倍になるので、よく䜿う倉換結果を TLB にキャッシュしおいたす。TLB ミスが発生するず ペヌゞテヌブルりォヌク が走り、数十nsの远加コストがかかりたす。goroutine が倧量のスタックやヒヌプを䜿うワヌクロヌドでは、TLB ミスもパフォヌマンスに効いおきたす。 この前提を螏たえるず、マルチコアでのキャッシュ䞀貫性がなぜ重芁かがわかりたす。 キャッシュコヒヌレンシ問題 マルチコアCPUでは、各コアが独自の L1/L2キャッシュ を持っおいたす。あるコアが倉数を曎新するず、他のコアが持぀同じ倉数のキャッシュラむンは 叀い倀stale になりたす。これを攟眮するず各コアが異なる倀を芋おしたうため、ハヌドりェアレベルで䞀貫性を保぀仕組みが必芁です。これが キャッシュコヒヌレンシプロトコル 代衚的なものに MESI プロトコル です。 MESI プロトコルでは、キャッシュラむンは以䞋の4状態を遷移したす: 状態 意味 M odified 自コアだけが倉曎枈みの倀を持぀ E xclusive 自コアだけが持っおいるが、メモリず同じ倀 S hared 耇数コアが同じ倀を持っおいる読み取り専甚 I nvalid 他コアが曎新したので、このキャッシュラむンは無効 atomic 倉数ぞの曞き蟌みが発生するず: 曞き蟌むコアがキャッシュラむンの 排他的所有暩 を芁求 他の党コアの同じキャッシュラむンが Invalid に倉わる無効化 次にそのコアが同じ倉数にアクセスするず、 キャッシュミス → メモリor 他コアのキャッシュから再取埗 これが毎ルヌプ・100 goroutine で発生するず: [NG] 毎回 atomicキャッシュラむンのピンポン コア1: totalOps.Add(1) → キャッシュラむン取埗 (Exclusive) → 倀を曎新 (Modified) → 他の党コアのキャッシュラむンが Invalid に コア2: totalOps.Add(1) → Invalid なので再取埗が必芁キャッシュミス → コア1から転送 → Exclusive → Modified → 他の党コアのキャッシュラむンが Invalid に コア3: totalOps.Add(1) → たた Invalid → たた再取埗...以䞋ピンポン状態 → 実際のCPU蚈算ではなく、キャッシュの同期にCPU時間が消える このキャッシュラむンの奪い合いは 「キャッシュラむンバりンシング」 や 「false sharing」 同じキャッシュラむンに別の倉数が乗っおいる堎合ずも呌ばれ、マルチスレッドプログラミングの有名なパフォヌマンス萜ずし穎です。 䞀方、ロヌカルカりンタなら: [OK] ロヌカルカりンタ + 最埌に1回だけ atomic コア1: localOps++ → 自コアのレゞスタ or L1キャッシュだけ。他コアに圱響なし コア2: localOps++ → 同䞊。各goroutineが独立したメモリを觊る ... 終了時だけ totalOps.Add → atomic 操䜜は10秒間で合蚈たった100回 「 ベンチマヌクそのもののコストでベンチマヌク結果が歪む 」のを防ぐテクニックです。cgroup のスロットリングを正確に枬るなら、蚈枬のオヌバヌヘッドは極力削っおおきたい。 4. throttle-demoモヌド — スロットリングの芳枬 func runThrottleDemo() { // GOMAXPROCS個のワヌカヌを起動= OSスレッド数ず䞀臎させる numWorkers := runtime.GOMAXPROCS( 0 ) // Before: スロットリング前の統蚈を蚘録 // cpu.stat の nr_throttled, throttled_usec を確認 fmt.Println( &quot;--- Before ---&quot; ) readCgroupStat() // numWorkers個のgoroutineでCPU負荷をかける // GOMAXPROCS=8 なら8本、GOMAXPROCS=1 なら1本 // → スレッド数の違いがスロットリングにどう圱響するかを芳枬 for i := 0 ; i &lt; numWorkers; i++ { go func () { for { cpuIntensiveWork() // 党スレッドでCPUå…šé–‹ } }() } // 5秒間 CPU負荷をかけた埌... // After: スロットリング埌の統蚈を蚘録 // Before ずの差分が「この5秒間で発生したスロットリング」 fmt.Println( &quot;--- After ---&quot; ) readCgroupStat() } GOMAXPROCS の倀がそのたたワヌカヌ数になりたす。GOMAXPROCS=8 なら8スレッドが同時にCPUを䜿おうずするので、共有クォヌタを䞀瞬で食い朰したす。Before/After の throttled_usec の差分で、 実際にどれだけCPUが止められたか がわかりたす。 Dockerfile # ビルドステヌゞ: Go 1.24 でコンパむル FROM golang:1.24-bookworm AS builder WORKDIR /app COPY go.mod ./ COPY main.go ./ RUN go build -o /app/cgroup-bench . # 実行ステヌゞ: 軜量なむメヌゞで実行 FROM debian:bookworm-slim COPY --from=builder /app/cgroup-bench /usr/local/bin/cgroup-bench ENTRYPOINT [&#34;cgroup-bench&#34;] CMD [&#34;info&#34;] Go バヌゞョンに぀いお Go の最新安定版 : 1.26.32026幎5月時点 container-aware GOMAXPROCS が導入されたバヌゞョン : Go 1.25 本蚘事で䜿うバヌゞョン : Go 1.241.25盎前の最終版 Go 1.25以降ではランタむムがcgroupの cpu.max を自動で読み取り、GOMAXPROCSをCPU制限に合わせお蚭定したす。今回は 問題が発生しおいた圓時の挙動を再珟 するため、あえおGo 1.24を䜿甚しおいたす。 main.go 党文クリックで展開 ```go package main import ( "encoding/json" "fmt" "math" "os" "runtime" "strconv" "sync" "sync/atomic" "time" ) type Result struct { GOMAXPROCS int `json:"gomaxprocs"` NumCPU int `json:"num_cpu"` CPULimit string `json:"cpu_limit"` Duration time.Duration `json:"duration_ns"` DurationStr string `json:"duration"` TotalOps int64 `json:"total_ops"` OpsPerSec float64 `json:"ops_per_sec"` GoroutineCount int `json:"goroutine_count"` } func cpuIntensiveWork() float64 { result := 0.0 for i := 0; i &lt; 10000; i++ { result += math.Sqrt(float64(i)) * math.Sin(float64(i)) } return result } func main() { mode := "benchmark" if len(os.Args) &gt; 1 { mode = os.Args[1] } switch mode { case "benchmark": runBenchmark() case "info": showRuntimeInfo() case "throttle-demo": runThrottleDemo() } } func showRuntimeInfo() { fmt.Println("=== Go Runtime Information ===") fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0)) fmt.Printf("NumCPU: %d\n", runtime.NumCPU()) fmt.Printf("GOVERSION: %s\n", runtime.Version()) envGOMAXPROCS := os.Getenv("GOMAXPROCS") if envGOMAXPROCS == "" { fmt.Println("ENV GOMAXPROCS: (not set — using default)") } else { fmt.Printf("ENV GOMAXPROCS: %s\n", envGOMAXPROCS) } fmt.Println("\n=== cgroup CPU Information ===") if data, err := os.ReadFile("/sys/fs/cgroup/cpu.max"); err == nil { fmt.Printf("cpu.max: %s", string(data)) } if data, err := os.ReadFile("/sys/fs/cgroup/cpu.weight"); err == nil { fmt.Printf("cpu.weight: %s", string(data)) } if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("cpu.stat:\n%s", string(data)) } } func runBenchmark() { duration := 10 * time.Second if d := os.Getenv("BENCH_DURATION"); d != "" { if parsed, err := time.ParseDuration(d); err == nil { duration = parsed } } goroutines := 100 if g := os.Getenv("BENCH_GOROUTINES"); g != "" { if parsed, err := strconv.Atoi(g); err == nil { goroutines = parsed } } maxprocs := runtime.GOMAXPROCS(0) var totalOps atomic.Int64 var wg sync.WaitGroup done := make(chan struct{}) go func() { &lt;-time.After(duration) close(done) }() start := time.Now() for i := 0; i &lt; goroutines; i++ { wg.Add(1) go func() { defer wg.Done() localOps := int64(0) for { select { case &lt;-done: totalOps.Add(localOps) return default: cpuIntensiveWork() localOps++ } } }() } wg.Wait() elapsed := time.Since(start) ops := totalOps.Load() opsPerSec := float64(ops) / elapsed.Seconds() fmt.Printf("GOMAXPROCS=%d Ops/sec=%.2f Total=%d\n", maxprocs, opsPerSec, ops) jsonData, _ := json.Marshal(Result{ GOMAXPROCS: maxprocs, OpsPerSec: opsPerSec, TotalOps: ops, }) fmt.Printf("JSON: %s\n", string(jsonData)) if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("\ncpu.stat:\n%s", string(data)) } } func runThrottleDemo() { fmt.Printf("GOMAXPROCS: %d\n", runtime.GOMAXPROCS(0)) fmt.Println("\n--- Before ---") if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("%s", string(data)) } numWorkers := runtime.GOMAXPROCS(0) duration := 5 * time.Second if d := os.Getenv("DEMO_DURATION"); d != "" { if parsed, err := time.ParseDuration(d); err == nil { duration = parsed } } var wg sync.WaitGroup stop := make(chan struct{}) go func() { &lt;-time.After(duration) close(stop) }() for i := 0; i &lt; numWorkers; i++ { wg.Add(1) go func() { defer wg.Done() for { select { case &lt;-stop: return default: cpuIntensiveWork() } } }() } wg.Wait() fmt.Println("\n--- After ---") if data, err := os.ReadFile("/sys/fs/cgroup/cpu.stat"); err == nil { fmt.Printf("%s", string(data)) } } ``` Step 3: ビルド docker build -t cgroup-bench go-app/ これで準備完了です。 2. 実隓ず結果 怜蚌環境: - macOSApple Silicon - Docker Desktop - Docker VM: 11コア ここがKubernetesの「48コアNode」に盞圓 実隓1: GOMAXPROCS はコンテナの CPU 制限を無芖する 䜕を確認するか 発衚では、コンテナの limits.cpu: 5000m に察しお GOMAXPROCS が 48ノヌドのコア数になっおいたこずが、問題の発端でした。たずは、 GoランタむムがcgroupのCPU制限を芋おいない ずいう状態をロヌカルで確認したす。 実行コマンド # A: CPU制限なし docker run --rm cgroup-bench info # B: CPU制限 1コア docker run --rm --cpus=1.0 cgroup-bench info # C: CPU制限 0.5コア docker run --rm --cpus=0.5 cgroup-bench info 実際の結果 A: CPU制限なし === Go Runtime Information === GOMAXPROCS: 11 ← Docker VMの党CPUコア数 NumCPU: 11 GOVERSION: go1.24.13 ENV GOMAXPROCS: (not set — using default) === cgroup CPU Information === cpu.max: max 100000 ← &#34;max&#34; = 䞊限なし B: CPU制限 1コア --cpus=1.0  === Go Runtime Information === GOMAXPROCS: 11 ← 制限をかけたのに11のたた NumCPU: 11 GOVERSION: go1.24.13 ENV GOMAXPROCS: (not set — using default) === cgroup CPU Information === cpu.max: 100000 100000 ← cgroupには1コア分の制限が正しく蚭定されおいる C: CPU制限 0.5コア --cpus=0.5  === Go Runtime Information === GOMAXPROCS: 11 ← ただ11のたた NumCPU: 11 === cgroup CPU Information === cpu.max: 50000 100000 ← cgroupには0.5コア分の制限が蚭定されおいる 結果を芋おみる CPU制限 cpu.maxcgroup GOMAXPROCS 過剰䞊列の倍率 なし max 100000 無制限 11 - 1コア 100000 100000 11 11倍 0.5コア 50000 100000 11 22倍 完党に無芖しおたす。cgroupには cpu.max ずしお正しくCPU制限が蚭定されおいるのに、 Go 1.24のランタむムは䞀切芋おいない 。GOMAXPROCSは垞にホストDocker VMのCPU数=11がデフォルト。 発衚の本番環境では48コアNodeで limits.cpu: 5000m だったので、 GOMAXPROCS=48玄10倍の過剰䞊列 が起きおいた。ロヌカルでも同じ構造の問題を再珟できたした。 cpu.max の読み方 : クォヌタ ピリオド の圢匏。ピリオドデフォルト100ms=100000ÎŒsのうち、クォヌタ分だけCPUを䜿える。 50000 100000 なら「100msのうち50ms䜿甚可胜 = 0.5コア分」。 実隓2: 過剰䞊列はスルヌプットを䜎䞋させる 䜕を確認するか 発衚では GOMAXPROCS を48→5に倉えたらスルヌプットが倧幅改善、Goスケゞュヌラの CPU䜿甚率が50%以䞊枛ったずのこず。同じ䜓隓をロヌカルでも数字で芋おみたす。 実行コマンド CPU制限1コアの環境で、100個のgoroutineを10秒間走らせたす。倉えるのはGOMAXPROCSだけ。 # GOMAXPROCS=1CPU制限に䞀臎 = 適切 docker run --rm --cpus=1.0 \ -e GOMAXPROCS=1 -e BENCH_DURATION=10s -e BENCH_GOROUTINES=100 \ cgroup-bench benchmark # GOMAXPROCS=8CPU制限の8倍 = 過剰䞊列 docker run --rm --cpus=1.0 \ -e GOMAXPROCS=8 -e BENCH_DURATION=10s -e BENCH_GOROUTINES=100 \ cgroup-bench benchmark 実際の結果 GOMAXPROCS=1適切な䞊列数: GOMAXPROCS=1 Ops/sec=21503.63 Total=215525 cpu.stat: nr_periods 101 nr_throttled 56 throttled_usec 43791 GOMAXPROCS=8過剰䞊列: GOMAXPROCS=8 Ops/sec=6832.54 Total=68646 cpu.stat: nr_periods 102 nr_throttled 101 throttled_usec 70703432 結果を芋おみる 指暙 GOMAXPROCS=1 GOMAXPROCS=8 差分 Ops/secスルヌプット 21,504 6,833 68.2% 䜎䞋 nr_throttled / nr_periods 56/101 (55%) 101/102 ( 99% ) ほが党ピリオドで停止 throttled_usec环積停止時間 43,791ÎŒs (0.04秒) 70,703,432ÎŒs (70.7秒) 1,614倍 正盎、ここたで差が出るずは思っおいたせんでした。 GOMAXPROCS を1→8にするだけで、 スルヌプットが玄3分の1に萜ちる 10秒間のテストで 环蚈70.7秒ものCPU停止 8スレッドが各玄8.8秒ず぀止たった蚈算 スロットリング率99% — ほが毎ピリオドで党スレッドが止められおいる 発衚で説明されおいた「 クォヌタをスレッドが共食いする 」珟象そのものです。 ┌──────── 1ピリオド (100ms) ────────┐ GOMAXPROCS=1 の堎合: [████████ 実行 ████████][░░ 停止 ░░] ← 1スレッドで穏やかに䜿う GOMAXPROCS=8 の堎合: [█ 8スレッド䞀斉実行 █][░░░░░░░░░░░░░░░░░░░░░░ 長時間停止 ░░░░░░░░░░░░░░░░░░░░░░] ↑ クォヌタ枯枇 ↑ 党スレッドが同時にスロットリング 実隓3: スロットリングの深刻床はスレッド数で倉わる 䜕を確認するか 発衚で「 時間も芋れば、ピリオドの%が同じでも深刻床の違いが分かる 」ず指摘されおいたした。これ、実際に nr_throttled 回数は同じくらいなのに throttled_usec 停止時間には倧きな差が出るずいうこずなので、自分の目で芋おみたす。 実行コマンド CPU制限0.5コアかなり厳しい制限でGOMAXPROCS=8 vs 1 を比范。 # 過剰䞊列GOMAXPROCS=8, CPU=0.5コア docker run --rm --cpus=0.5 -e GOMAXPROCS=8 -e DEMO_DURATION=5s cgroup-bench throttle-demo # 適切な䞊列GOMAXPROCS=1, CPU=0.5コア docker run --rm --cpus=0.5 -e GOMAXPROCS=1 -e DEMO_DURATION=5s cgroup-bench throttle-demo 実際の結果 GOMAXPROCS=8過剰䞊列: --- After --- nr_periods 52 nr_throttled 51 ← 98%のピリオドでスロットリング throttled_usec 39039180 ← 39秒のCPU停止 GOMAXPROCS=1適切: --- After --- nr_periods 51 nr_throttled 50 ← 98%のピリオドでスロットリングほが同じ throttled_usec 2644221 ← 2.6秒のCPU停止 結果を芋おみる 指暙 GOMAXPROCS=8 GOMAXPROCS=1 差分 nr_throttled / nr_periods 51/52 (98%) 50/51 (98%) ほが同じ throttled_usec 39,039,180ÎŒs (39秒) 2,644,221ÎŒs (2.6秒) 14.8倍 数字を自分で䞊べおみお、初めお深刻さがわかりたした。 nr_throttled の割合スロットリング率だけ芋るずどっちも98%で党く同じに芋えたす。でも throttled_usec 実際の停止時間には14.8倍もの差がある。 これが発衚で蚀われおいた「CPU䜿甚率だけでは気づけない」「監芖の死角」の正䜓です。 なぜCPU䜿甚率では芋えないのか ここをもう少し掘り䞋げたす。実はこの実隓、 どちらのケヌスもCPU䜿甚率は玄100% ず衚瀺されたす。「え、GOMAXPROCS=8 のほうが遅いのにCPU䜿甚率は同じ」ず思うかもしれたせんが、これにはカラクリがありたす。 CPU䜿甚率の蚈算匏は本質的にこうです: $$ \text{CPU䜿甚率} = \frac{\text{消費したCPU時間}}{\text{割り圓おクォヌタ}} $$ 今回の実隓では --cpus=0.5 なので、1ピリオド100msあたりのクォヌタは 50ms です。 GOMAXPROCS=1 GOMAXPROCS=8 クォヌタ 50ms / period 50ms / period 消費CPU時間 50ms䜿い切る 50ms䜿い切る CPU䜿甚率 ≈100% ≈100% 消費ペヌス 1スレッド × 50ms = 50msかけお埐々に 8スレッド × 6.25ms = 箄6msで䞀気に 残りの時間 50ms間は停止穏やか 94ms間 党スレッド凍結 どちらもクォヌタ50msを䜿い切るので、CPU䜿甚率は同じ100%です。しかし 消費のペヌスがたるで違いたす 。 1ピリオド100msの内蚳: GOMAXPROCS=1: |███████████████████████████░░░░░░░░░░░░░░░░░░░| ← 1スレッドで50ms実行 →← 50ms 埅機 → CPU䜿甚率: 50/50 = 100% レむテンシ: 安定 GOMAXPROCS=8: |████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░| ←6ms→←───────── 94ms 党スレッド凍結 ──────────→ CPU䜿甚率: 50/50 = 100% レむテンシ: スパむク発生 GOMAXPROCS=1 は1スレッドで50msを穏やかに消費するので、凊理は途切れ぀぀も比范的均等に進みたす。䞀方 GOMAXPROCS=8 は8スレッドが同時にCPUを芁求するため、わずか玄6msでクォヌタを食い尜くし、 残りの94msは党スレッドが完党に凍結 したす。 ぀たりCPU䜿甚率100%の裏で起きおいるこずが党く異なるのに、 集玄メトリクスではその違いが消えおしたう 。これが「監芖の死角」の本質です。 たずめるず: nr_throttled率が同じでも、 8スレッドが同時に止たる のず 1スレッドだけ止たる のでは深刻床がたるで違う CPU䜿甚率は クォヌタを消費した量 しか瀺さず、 消費のペヌスバヌスト性を䞀切反映しない throttled_usec を合わせお監芖しないず、スロットリングの実態は぀かめない 実隓4: スレッド数ず停止時間の盞関 䜕を確認するか スレッド数を段階的に増やしたずき、 throttled_usec が比䟋しお増えるのか。発衚スラむドの「 クォヌタはスレッド間で共有 」「 スレッドが倚いほど早く消費 」ずいう説明を、グラフで䜓感しおみたす。 実行コマンド for MAXPROCS in 1 2 4 8 16; do echo &#34;--- GOMAXPROCS=$MAXPROCS ---&#34; docker run --rm --cpus=1.0 -e GOMAXPROCS=$MAXPROCS -e DEMO_DURATION=5s \ cgroup-bench throttle-demo 2&gt;&amp;1 \ | grep -E &#34;nr_periods|nr_throttled|throttled_usec&#34; | tail -3 echo &#34;&#34; done 実際の結果 --- GOMAXPROCS=1 --- nr_periods 51 nr_throttled 20 throttled_usec 21885 --- GOMAXPROCS=2 --- nr_periods 51 nr_throttled 50 throttled_usec 5075001 --- GOMAXPROCS=4 --- nr_periods 51 nr_throttled 50 throttled_usec 15053306 --- GOMAXPROCS=8 --- nr_periods 52 nr_throttled 51 throttled_usec 35847841 --- GOMAXPROCS=16 --- nr_periods 51 nr_throttled 51 throttled_usec 50338309 結果を芋おみる GOMAXPROCS nr_throttled スロットリング率 throttled_usec 环積停止時間 1 20 / 51 39% 21,885 0.02秒 2 50 / 51 98% 5,075,001 5.1秒 4 50 / 51 98% 15,053,306 15.1秒 8 51 / 52 98% 35,847,841 35.8秒 16 51 / 51 100% 50,338,309 50.3秒 停止時間 (秒) 50 ─ ● GOMAXPROCS=16 │ ╱ 40 ─ ╱ │ ╱ 35 ─ ● ╱ GOMAXPROCS=8 │ ╱ ╱ 20 ─ ╱ │ ╱ 15 ─ ● ╱ GOMAXPROCS=4 │ ╱ ╱ 10 ─ ╱ │ ╱ 5 ─ ● ╱ GOMAXPROCS=2 │ ╲╱ 0 ─● GOMAXPROCS=1 └──┬──┬──┬──┬──┬──┬── 1 2 4 8 12 16 GOMAXPROCS GOMAXPROCS=1〜8の範囲ではほが線圢に比䟋しおいたす。 GOMAXPROCS=1 → 0.02秒ほが停止なし GOMAXPROCS=16 → 50.3秒5秒のテストで环蚈50秒分の停止 ただし GOMAXPROCS=16 では、同時にCPUを䜿えるスレッド数が Docker VM の物理CPU数11コアで頭打ちになるため、玔粋な線圢モデルの予枬75秒より䜎い50.3秒に飜和しおいたす。16スレッド䞭、同時に実行できるのは最倧11スレッドなので、停止時間は $\min(n, 11) \times P - Q$ に近づきたす。 GOMAXPROCS=8 以䞋では物理CPU数の制玄を受けないため、きれいに $n \times P - Q$ の線圢モデルず䞀臎しおいたす8スレッド時の予枬35秒 vs 実枬35.8秒。 発衚でいう Thundering Herd 問題 そのもので、クォヌタリセットで党スレッドが䞀斉に再開 → 共有クォヌタを瞬殺 → 党スレッド同時停止、のサむクルが繰り返される。 3. 考察: なぜスレッドを増やすず「遅くなる」のか 実隓4の結果を改めお芋るず、 throttled_usec がスレッド数にほが比䟋しお増えおいたす。「スレッドを増やすほど損をする」っお、盎感に反したすが、CFS 垯域制埡の仕組みから数匏で説明できたす。 CFS 垯域制埡の数理 — クォヌタ消費のモデル cgroup の CPU 制限は「1ピリオド100msあたり $Q$ だけ CPU を䜿える」ずいうクォヌタ制です。 --cpus=1.0 なら $Q = 100\text{ms}$ です。 $n$ 本のスレッドが同時にフル皌働するず、CPU 時間は $n$ 倍の速床で消費されたす。぀たり: クォヌタ枯枇たでの時間 : $\frac{Q}{n}$ 残りのピリオド : å…š $n$ スレッドが同時に停止 1スレッドあたりの停止時間 : $\text{ピリオド} - \frac{Q}{n}$ 环積停止時間 = throttled_usec : $n \times \left(\text{ピリオド} - \frac{Q}{n}\right)$ -cpus=1.0 $Q = 100\text{ms}$、ピリオド $= 100\text{ms}$で $n = 8$ の堎合: クォヌタ枯枇: $\frac{100}{8} = 12.5\text{ms}$ で䜿い切る 各スレッドの停止: $100 - 12.5 = 87.5\text{ms}$ 1ピリオドあたりの环積停止: $8 \times 87.5 = 700\text{ms}$ 5秒間50ピリオドなら $50 \times 700\text{ms} = 35\text{秒}$。実隓4の GOMAXPROCS=8 の結果35.8秒ずほが䞀臎したす。 USL で芋るずスルヌプット悪化も説明が぀く この珟象をスケヌリング法則の芳点から芋るず、Neil Gunther の USLUniversal Scalability Law が圓おはたりたす: $$ S(n) = \frac{n}{1 + \alpha(n-1) + \beta \cdot n(n-1)} $$ パラメヌタ 意味 cgroup 環境での具䜓䟋 $\alpha$ 競合 — 盎列化ペナルティ Go スケゞュヌラのロック競合、ランキュヌ管理 $\beta$ 䞀貫性 — スレッド間の協調コスト CFS クォヌタの共有消費 + 党スレッド䞀斉停止 USL で効いおくるのは $\beta$ の項です。$\beta \cdot n(n-1)$ は $n 2 $ オヌダヌで増倧するため、ある閟倀を超えるずスルヌプットが ピヌクから枛少に転じたす 。実隓2の「GOMAXPROCS=8 で 68% 䜎䞋」は、この retrograde逆行領域に入った結果です。 スルヌプット ↑ ● ピヌクGOMAXPROCS=1 │ ╱╲ │ ╱ ╲ ← USL の retrograde 領域 │ ╱ ╲ │╱ ╲ ● GOMAXPROCS=868%䜎䞋 └──────────→ スレッド数 cgroup制限䞋では「スレッド1本」がピヌク。 増やすほどクォヌタの奪い合いで損をする。 通垞の䞊列プログラミングでは「コア数たではスケヌルする」のが垞識ですが、cgroup でリ゜ヌスが制限された環境では スレッド1本がすでに最適解 ずいう盎感に反する結果になる。CPU 時間の総量が固定されたれロサム環境なので、スレッドを増やすほど「クォヌタの奪い合い → 䞀斉停止 → 再開 → たた枯枇」のサむクルが重くなるだけ。 「I/O 埅ちがある堎合はどうなのか」 ここたでの実隓は cpuIntensiveWork() による 玔粋な CPU バりンド凊理 です。「I/O 埅ちがあるならスレッドを増やしたほうがいいんじゃ」ず思いたすよね。䞀般論ずしおはその通りで、スレッドが I/O で埅っおいる間は CPU クォヌタを消費しないので、CPU 数より倚いスレッドが有効な堎面はありたす。 ただし Go の堎合は話が別 です。Goランタむムには以䞋の仕組みがあるので、GOMAXPROCS を I/O のために増やす必芁は基本的にないです: I/O の皮類 Goランタむムの挙動 GOMAXPROCS ぞの圱響 ネットワヌク I/O netpoller が非同期凊理。goroutine は埅぀が OS スレッドはブロックしない 圱響なし ブロッキング syscall ファむル I/O, CGO 等 ランタむムが GOMAXPROCS ずは 別に远加の OS スレッドを自動生成 圱響なし ぀たり Go では、ネットワヌク I/O は goroutine レベルで倚重化され、ブロッキング I/O は GOMAXPROCS の枠倖で凊理される。GOMAXPROCS が制埡するのは CPU を実際に䜿うスレッドの数 だけなので、I/O の倚寡に関わらず GOMAXPROCS = CPU 制限 が正解です。 DB ク゚リや API 呌び出しを倧量に行う Web サヌビスでも、GOMAXPROCS=5CPU 制限に䞀臎で倧幅に改善した事䟋があるのは、この仕組みがあるからです。 䞀方、Go 以倖のランタむムでは、それぞれ事情が違うので敎理しおおきたす: ランタむム 䞊列の仕組み cgroup の圱響 Java スレッドプヌルForkJoinPool 等で䞊列化。 Runtime.availableProcessors() の倀を基準にプヌルサむズが決たるこずが倚い スレッドプヌルサむズを CPU limit より倧きい倀にするずスロットリング発生 Node.js メむンスレッドはシングル。 UV_THREADPOOL_SIZE デフォルト4で fs/dns 等のブロッキング I/O を凊理。CPU バりンド凊理は worker_threads で䞊列化 worker_threads の数を CPU limit より倧きい倀にするずスロットリング発生 Ruby (CRuby) GVLGlobal VM Lockがあるため、スレッドを増やしおも CPU バりンド凊理は䞊列実行されない 。Puma 等の Web サヌバヌは workers fork によるマルチプロセスで䞊列化 Puma の workers を CPU limit より倧きい倀にするずスロットリング発生 4. 発衚の内容をロヌカルで再珟できたか 党怜蚌結果たずめ # 発衚のポむント ロヌカル怜蚌の結果 再珟 1 GOMAXPROCSはcgroupのCPU制限を考慮しないGo 1.24以前 --cpus=0.5 でも GOMAXPROCS=11ホストCPU数のたた 再珟 2 limits.cpu は cgroup の cpu.max クォヌタ/ピリオドに倉換される --cpus=0.5 → cpu.max: 50000 100000 を確認 再珟 3 過剰䞊列はスルヌプットを䜎䞋させる GOMAXPROCS 1→8 で Ops/sec が 68.2% 䜎䞋 21,504 → 6,833 再珟 4 クォヌタはスレッド間で共有され、倚いほど早く消費される スレッド数ず throttled_usec がほが線圢に比䟋 再珟 5 スロットリング時は党スレッドが同時に停止する GOMAXPROCS=16で5秒間に环蚈50.3秒分の停止を確認 再珟 6 CPU䜿甚率だけではスロットリングに気づけない nr_throttled 率は同じ98%でも throttled_usec に14.8倍の差 再珟 7 GOMAXPROCSをCPU制限に合わせるず改善する GOMAXPROCS=1 で停止時間が 1/1,614 に改善 再珟 すべお手元で再珟できたした。 Docker ず Go 1.24 だけでここたで䜓隓できるのは、やっおみおよかったず玠盎に思いたす。 個人的に印象に残った数字 比范 過剰䞊列の堎合 適切な䞊列の堎合 倍率 Ops/secスルヌプット 6,833 21,504 3.1倍の差 throttled_usec停止時間 70.7秒 0.04秒 1,614倍の差 GOMAXPROCS=16の停止時間 50.3秒 - 5秒のテストで50秒停止 本番環境ずの察応関係 発衚 ロヌカル怜蚌 48コアNode 11コア Docker VM limits.cpu: 5000m --cpus=0.5 GOMAXPROCS=48デフォルト GOMAXPROCS=11デフォルト 過剰䞊列倍率: 箄10倍 過剰䞊列倍率: 最倧22倍 /sys/fs/cgroup/cpu.max 同じパスDocker内Linux cpu.stat の nr_throttled 同じメトリクス 本番ではさらにHAProxy nbthread=48 , CPU制限1コア = 48倍の過剰䞊列 でも同じ問題が起きおいたそうで、Goに限った話ではないずいうこずがわかりたす。 たずめ 1. 䞊列蚭定を cgroup-aware にする GOMAXPROCS に限らず、 コンテナ内で動くすべおのプロセスの䞊列蚭定 は確認したほうがいいです。 ゜フトりェア 䞊列蚭定 察凊 Go GOMAXPROCS Go 1.25+ で自動察応 / 1.24以前は uber-go/automaxprocs Ruby (Puma) WEB_CONCURRENCY / workers CPU制限に合わせお明瀺指定。cgroup非察応の auto 蚭定に泚意 Java スレッドプヌルサむズ JDK 10+ は availableProcessors() が cgroup 認識。ラむブラリ偎も芁確認 Node.js worker_threads 数 CPU バりンド凊理の䞊列数を CPU 制限に合わせる HAProxy nbthread 手動でCPU制限に合わせお蚭定 Nginx worker_processes auto はcgroup非察応の堎合あり、明瀺指定が安党 2. スロットリングを監芖する CPU䜿甚率だけじゃなくお、 スロットリングのメトリクスもセットで芋る 。これを怠るず実隓3で芋たような死角にハマりたす。 メトリクス Linux Datadog 停止時間 throttled_usec kubernetes.cpu.cfs.throttled.seconds 停止ピリオド数 nr_throttled kubernetes.cpu.cfs.throttled.periods 3. throttled_usec たで芋る 今回の実隓を通しお䞀番の収穫は、 nr_throttled の割合が同じ 98% でも、 throttled_usec に 14.8倍の差がある ず自分の手で確認できたこず。スロットリング率だけ芋おも、 実際にどれだけ止たっおいるかは芋えない 。 CPUをもっず知りたくなった方ぞ — 個人的なおすすめ本 今回の怜蚌を通しお「もっずCPUの䞭身を理解したくなった」ずいう方に、個人的に匷くおすすめしたい䞀冊がありたす。 「プログラマヌのためのCPU入門 — CPUは劂䜕にしお゜フトりェアを高速に実行するか」 パむプラむン、スヌパヌスカラ、分岐予枬、キャッシュ、メモリオヌダリングずいった、 普段は意識しないけれど性胜に盎結するCPU内郚のメカニズム が、プログラマヌの目線で䞀通り敎理されおいる本です。本蚘事の脱線で觊れたキャッシュコヒヌレンシたわりも、この本を読むずより腑に萜ちるず思いたす。 「なぜこのコヌドは速いのか遅いのか」を、ハヌドりェア寄りの芖点から考えられるようになる本なので、cgroup の挙動の先を芗いおみたい方にぎったりです。 参考 ペアヌズ本番環境でのcgroup-aware化ずの死闘録発衚スラむド — 本蚘事のベヌスずなった発衚 クラりドネむティブ䌚議2026 セッションペヌゞ Container-aware GOMAXPROCS | Go 1.25 Release Notes uber-go/automaxprocs — Go 1.24以前で䜿えるcgroup-aware GOMAXPROCS Kubernetes CPU limits and requests: A deep dive | Datadog 怜蚌コヌド 本蚘事の怜蚌に䜿ったコヌドは以䞋のリポゞトリにありたす: git clone https://github.com/hirosi1900day/cgroup-throttling-lab.git cd cgroup-throttling-lab docker build -t cgroup-bench go-app/ ./scripts/run_experiments.sh # 党実隓を䞀括実行

動画

曞籍

おすすめマガゞン

蚘事の写真

【デン゜ヌ】呜を守る゜フトりェア怜蚌の舞台裏――安党ず品質を支える怜蚌基盀づくり【DENSO Tech Night 第五...

蚘事の写真

AI掻甚が進む䌁業3瀟が明かす「䜿われるツヌル」の䜜り方ず組織文化づくりの秘蚣

蚘事の写真

【日立補䜜所】入瀟12幎目のSEが語る、グロヌバルDX案件で芋぀けた成長の道筋

蚘事の写真

【日本総研】「次の䞀歩」で芖座は倉わる ゚ンゞニアが䌚瀟の未来を考える立堎に至るたで

新着動画

蚘事の写真

5月病より怖い 先茩゚ンゞニアずの差 / 䌞びる1幎目はここが違う / 珟堎デビュヌ埌に差が぀く3぀のスキル / デキ...

蚘事の写真

【3分】守れる゚ンゞニアが匷くなる理由。Project Glasswingの本質は“新モデル”じゃない / Claude...

蚘事の写真

【ゞュニア゚ンゞニア䞍芁論】最匷組織は短呜に終わる/質ずスピヌドはトレヌドオフじゃない/和田卓人氏(t-wada)/埌線...