GitHubのパフォーマンス・エンジニアリング・チームは、利用率が上がるにつれてCPUのパフォーマンスがどのように低下するのか、そしてシステムのキャパシティとどのように関係しているのかを評価しました。
はじめに
GitHubパフォーマンスエンジニアリングチームは、様々な負荷条件下でシステムのパフォーマンスを観察する実験を定期的に行っています。これらの実験で一貫しているのは、CPU使用率がシステム・パフォーマンスに与える影響の大きさです。CPU使用率が上昇すると、待ち時間の増加につながり、システム効率の最適化する余地があることがわかります。この課題に取り組むことで、マシンを追加する必要性を減らしながらパフォーマンスレベルを維持することができ、最終的に非効率を防ぐことができます。
CPU 使用率の上昇とレイテンシの増加の相関関係は認識していましたが、様々な段階における具体的な閾値と影響をより詳細に調査する機会があると考えました。さまざまな CPU ファミリーを搭載した多様なインスタンス・タイプから、各 CPU モデル固有のパフォーマンス特性を理解することに注力しました。この深い洞察により、よりスマートでデータドリブンの意思決定が可能になり、より効率的で信頼性の高いインフラストラクチャのプロビジョニングが可能になりました。
このような目標を念頭に、私たちはこれらの洞察を明らかにするために、調査と実験の新たな旅に乗り出しました。
実験のセットアップ
この種の実験のために正確なデータを収集するのは容易なことではありませんでした。可能な限り本番に近いワークロードからデータを収集すると同時に、負荷の異なるフェーズにおけるシステムの挙動を把握する必要がありました。CPUの使用パターンはワークロードによって異なるため、私たちは主に主力ワークロードに焦点を当てました。しかし、負荷を高めるとパフォーマンスにわずかな不一致が生じる可能性があるため、私たちの目標はユーザーの混乱を最小限に抑えることでした。
幸いなことに、1年前、パフォーマンス・エンジニアリング・チームは、コードネームLarge Unicorn Collider(LUC)と呼ばれる、これらの要件を満たすように設計された環境を開発しました。この環境は、GitHubのKubernetesクラスタ環境のごく一部で動作し、GitHub内の主要なワークロードと同じアーキテクチャと構成をミラーリングします。また、専用マシンでホストする柔軟性もあり、他のワークロードからの干渉や他のワークロードとの干渉を防ぎます。通常、LUC環境はアイドルのままですが、必要に応じて、少量の調整可能なトラフィックを向けることができます。このトラフィックのアクティブ化、非アクティブ化には数秒しかかからないため、パフォーマンスに懸念が生じた場合に迅速に対応できます。
CPU使用率の影響を正確に評価するために、まず、専用マシンの1つでホストされているLUC Kubernetesポッドに適度な本番トラフィックを送信してベースラインを確立しました。これにより、比較のためのベンチマークが得られました。重要なのは、LUCポッドによって処理されたリクエストの数が実験を通して一定に保たれ、時間の経過とともに一貫したCPU負荷が確保されたことです。
ベースラインが設定されると、「ストレス 」と呼ばれるツールを使ってCPU利用率を徐々に上げていきます。このツールは、ランダムな処理タスクを実行することで、指定された数のCPUコアを人工的に占有します。インスタンスタイプごとにCPUコア数が異なるため、それに応じてステップを調整しました。しかし、すべてのインスタンスに共通する要因は、CPU使用率の合計でした。
注:これは、実際の本番ワークロードによって生成される負荷と直接1対1で比較するものではありません。ストレスツールは数学的処理を継続的に実行しますが、実稼働ワークロードはI/O処理や割り込みを含み、システムリソースに異なる要求を与えます。それでもなお、このアプローチは、CPUが負荷のかかった状態でどのように動作するかについて、貴重な洞察を与えてくれます。
環境のセットアップと計画の完了後、影響を分析するために可能な限り多くのデータを収集しました。
結果
実験のセットアップが完了したので、収集したデータを検証してみましょう。前述の通り、異なるインスタンスタイプでプロセスを繰り返しました。各インスタンスタイプはユニークな挙動を示し、パフォーマンスが低下し始める閾値も様々でした。
予想通り、CPU使用率が上昇するにつれて、すべてのインスタンスタイプでCPU時間が増加しました。以下のグラフは、CPU利用率の増加に伴うリクエストあたりのCPU時間を示しています。
リクエストあたりのCPU時間とCPU使用率の比較
インスタンスタイプ間のレイテンシの違いは、CPUモデルのバリエーションに起因するものであることが予想されます。レイテンシの増加率に注目すると、より意味のある洞察が得られるかもしれません。
レイテンシ増加率 vs CPU使用率
どちらのグラフでも、1本の線が他の線よりも乖離しているのが目立ちます。このケースについては、このあと詳しく検証します。
ターボ・ブースト効果
興味深い観察は、利用率の増加に伴ってCPU周波数がどのように変化するかであり、これはインテル社のターボブーストテクノロジーに起因しています。今回使用したインスタンスはすべてIntel CPUを搭載しているため、ターボブーストの影響はすべてのインスタンスで顕著です。下のグラフでは、CPU使用率が上昇するにつれてCPU周波数が低下している様子がわかります。赤い矢印はCPU利用率を示しています。
CPUコア周波数
CPU使用率が低いレベル(約30%以下)にとどまっているときは、コア周波数の増加の恩恵を受け、CPU時間が速くなり、その結果、全体的なレイテンシが低くなります。しかし、より多くのCPUコアの需要が高まり、使用率が上昇すると、CPUの熱と電力の限界に達する可能性が高くなり、周波数が低下します。要するに、CPUの使用率が低ければ低いほど性能は向上し、使用率が高ければ高いほど性能は低下します。例えば、CPU使用率が約30%の特定のノードで実行されているワークロードは、CPU使用率が50%を超えた場合、同じVM上の同じワークロードと比較して、より速い応答時間を示します。
ハイパースレッディング
パフォーマンスの変化に影響を与える要因は、CPU周波数の変動だけではありません。ハイパースレッディングは、1つの物理CPUコアを2つの仮想コアとして動作させるインテル社のテクノロジーです。物理コアは1つしかないが、Linuxカーネルはこれを2つの仮想CPUコアとして認識します。カーネルはこれらのコアにCPU負荷を分散させようとし、物理コア1つにつき1つのハードウェアスレッド(仮想コア)だけをビジー状態に保つことを目指します。このアプローチは、CPU使用率があるレベルに達するまで有効です。この閾値を超えると、両方の仮想CPUコアを完全に利用することができなくなり、その結果、通常の動作に比べてパフォーマンスが低下します。
CPU使用率の「黄金比」を見つける
利用率の低いノードは、データセンター内のリソース、電力、スペースの浪費につながり、利用率の高いノードも非効率を生みます。前述のとおり、CPU使用率が高くなるとパフォーマンスが低下するため、リソースの追加が必要であるかのような誤解を与え、結果として過剰プロビジョニングのサイクルが発生します。この問題は、非同期モデルに従わないブロッキング作業負荷で特に顕著です。CPUの性能が低下すると、各プロセスが1秒間に処理できるタスクの数が少なくなり、既存の容量では不十分となります。最適なバランス(CPU使用率の「黄金比」)を達成するためには、パフォーマンスを大幅に損なうことなく効率を確保するために、CPU使用率が十分に高くなる閾値を特定する必要があります。ノードをこの閾値の近くに保つよう努力することで、既存のソフトウェアとともに現在のハードウェアをより効果的に活用できるようになります。
利用率の上昇に伴ってCPU時間がどのように増加するかを示す実験データがすでにあるため、この閾値を特定する数学的モデルを開発することができます。まず、特定のユースケースにおいて、CPU時間の劣化が何パーセントまで許容できるかを決定する必要があります。これは、ユーザーの期待やパフォーマンスのサービスレベルアグリーメント(SLA)に依存する場合があります。この閾値を設定すれば、許容範囲内に収まる CPU 使用率のレベルを選択するのに役立ちます。
CPU使用率対CPU時間(レイテンシ)をプロットし、次のポイントを見つけることができます:
CPU使用率が十分に高く、リソースが十分に使用されていない。
CPU時間の劣化が許容限度を超えない。
上記のデータから得られた具体的な例を、以下のグラフに示します。
P50レイテンシの増加率 vs CPU使用率
この例では、CPU時間の劣化を40%未満にすることを目指しており、これは特定のインスタンスのCPU使用率61%に相当します。
異常値ケース
前述したように、いくつかの異常値データポイントを表示する特定のインスタンスがありました。私たちの実験では、特定のインスタンスが、メーカー側で宣伝されている最大 ターボブースト CPU 周波数を達成していないという、すでに認識されている問題が確認されました。その代わりに、CPU使用率が低い状態では、最大値を下回る安定したCPU周波数が観測されました。以下の例では、メーカー側で宣伝されているターボブースト周波数が3GHz以上であるCPUファミリーのインスタンスが、2.8GHzの最大CPU周波数しか示していません。
CPUコア周波数
この問題は、無効化されたCPU Cステートが原因であることが判明しました。これは、CPUコアが使用されていないときでも、CPUコアが停止しないようにするものです。その結果、これらのコアはターボドライバによって「ビジー」と認識され、より高いCPU周波数でターボブーストの利点を活用する能力を制限していました。Cステートを有効にし、アイドルモード中の最適化と電力削減を可能にすることで、期待通りのターボブースト動作が確認されました。この変更は、テスト・ワークロードが費やしたCPU時間に即座に影響を与えました。以下の画像は、Cステートの調整後に報告されたCPU周波数とレイテンシの迅速な変化を示しています。
CPU コア周波数
リクエストの P50 CPU 時間
CPU 時間の変化率を再評価したところ、すべてのインスタンスで同じような挙動が見られました。
P50レイテンシの増加率 vs CPU使用率
まとめ
我々の目的は、複雑なシステムからのデータを使用して、我々の理論を検証することであり、予想していたように、さまざまな CPU ファミリーで CPU 使用率が増加するとパフォーマンスが低下することが確認されましたが、最適な CPU 使用率の閾値を特定することで、パフォーマンスと効率のバランスを改善し、インフラストラクチャのコスト効率とパフォーマンスの両方を維持することができます。今後、これらの洞察は、リソース・プロビジョニング戦略に反映され、ハードウェア投資の効果を最大化するのに役立ちます。
最後まで読んでいただき、ありがとうございました!@adrmike
、@schlubbi
、@terrorobe
、@github/compute-platform
、そして最後に@github/performance-engineering
、これらの実験、データ分析を通して貴重な助力をいただき、また内容の正確性と一貫性を確認するためにレビューをしてくれたチームに特別なエールを送ります。
The postBreaking down CPU speed: How utilization impacts performance appeared first on The GitHub Blog .