サーバーのパフォーマンスを上げるには プロセスとの親和性 とNUMAをターゲットとした方法で認識することで、スレッド、コア、メモリーを互いに関連付けて最適に編成することができます。これにより、多くのアプリケーションを使用するホスティング環境において、レイテンシーを削減し、スループットを向上させ、一貫した応答時間を達成することができます。.
中心点
具体的な設定をする前に、目標、ワークロード・パターン、既存のハードウェア・トポロジーを明確にする。どのスレッドが特にメモリを消費し、どのプロセスが短い応答時間を必要としているかを分析する。NUMAノードごとに利用可能なコア数とローカルRAMの容量を検討します。ノードごとにサービスをバンドルする計画なので、次のようなことができる。 CPUロカリティ が維持されている。私は、誤った仮定を避けるために、ベンチマークとモニタリングですべての変化を測定する。.
- 親和性プロセスをコア・グループにバインドする
- NUMAメモリをローカルに保つ
- トポロジーノードごとのスケール
- モニタリングリモートアクセスを可視化する
- ホスティングハイパーバイザーの配置を制御する
プロセス・アフィニティとは何ですか?
と一緒に プロセスとの親和性 プロセスやスレッドがどのCPUコアで実行されるかは、オペレーティング・システムが自由に決めるのではなく、私が指定する。これによってキャッシュの内容が一貫性を保ち、キャッシュ・ミスやコンテキスト・スイッチを減らすことができる。スレッドがL1/L2/L3キャッシュを効果的に使用し、コア間をジャンプしないようにスレッドを固定する。これにより、高負荷時のレイテンシの予測可能性が向上し、予約コアの均一な利用が保証される。実践的な導入については、この ホスティングにおけるCPUアフィニティ, 典型的なピン止めのバリエーションを比較するために使っているからだ。.
NUMAを理解する:ローカルアクセスとリモートアクセス
NUMA は作業メモリをノードに分割し、各ノードは特定のCPUソケットに密接に結合している。スレッドは、他のノードのリモートメモリよりもローカルRAMに速くアクセスする。この非対称性は、特に多くのコアと大容量のRAMを使用する実際のワークロードに大きな影響を与える。そのため、私はスレッドとそのメモリ・アクセスを共有ノードに割り当てて、レイテンシを減らし、帯域幅を増やしている。トポロジーをより深く掘り下げたい場合は、以下の実践的なヒントをチェックしてほしい。 サーバーのNUMAノード そして、日常生活における効果を測定する。.
オペレーティングシステムとアプリにおけるNUMAの認識
起動させる NUMAアウェアネス オペレーティングシステム、ハイパーバイザー、アプリケーションで、メモリがローカルに割り当てられるようにする。可能であれば、インスタンスのスレッドをノード間で分散させるのではなく、同じNUMAノードのコア上に保持する。ローカルRAMに大きなヒープやバッファを作成し、高価なリモートアクセスが発生しないようにします。アプリケーションに複数のワーカーがいる場合は、干渉を避けるためにノードごとにプールで構成します。これにより、CPUとメモリの割り当てが明確になり、レスポンスタイムが顕著に短縮される。.
アフィニティとNUMAの相互作用
親和性 NUMAスケジューリングなしで、メモリがリモートノードにある場合、可能性を無駄にする。同様に、NUMAスケジューリングがスレッドを頻繁に移動させるのであれば、NUMAスケジューリングはほとんど役に立ちません。そのため、私はスレッドを特定のノードのコアにバインドし、並列にローカルメモリを確保します。アプリケーションの規模を拡大する場合は、ノードを追加する前に、まずノードをいっぱいにする。このコアの固定とメモリーポリシーの結合により、負荷がかかっても一定のレイテンシ・プロファイルが生成される。.
ハードウェアとファームウェアのチューニング(UEFI/BIOS)
アフィニティとNUMAを機能させるために、私はファームウェアのベースを安定したものに設定した。クロックとレイテンシの変動を最小限に抑えるため、アグレッシブな省エネオプションではなく、一貫したパフォーマンスモードを好みます。私がチェックする重要なポイント
- 性能プロファイル:バランス型ではなく最大電力/性能型。効率よりもレイテンシが重要な場合は低Cステートを制限する。.
- ターボ/ブースト戦略:Pコアの変動を避けるため、オンデマンドで決定論的なブーストを行う。.
- SMT/ハイパースレッディング:ワークロードに応じてテストする。ハードレイテンシSLAの場合は、クリティカルなスレッドを物理コアに固定し、SMT兄弟を分離することが多い。.
- メモリ・インターリーブ:NUMA最適化のため、ノードの区切りが明確になるように無効化。.
- メモリチャネル:ノードごとにDIMMスロットを対称に構成し、最大帯域幅を実現。.
コンフィギュレーション・パス:分析からピン止めまで
私はトポロジーのレコーディングから始める。 lscpu, numactl -hardwareまたはhwlocを使う。それから各サービスに必要なコア数を定義し、ノードに割り当てる。割り当ての再現性が保たれるように、tasksetを使うか、systemdのオプションを使ってピン留めを実装する。テスト中、レイテンシーとスループットが良い比率になるまでコアグループのサイズを調整する。CPU負荷の高いサービスが同じコアプールを共有し、お互いのキャッシュを置き換えないようにする。.
Linuxでは、cgroups (v2)を使ってアフィニティとメモリー・ポリシーを宣言的に設定するのが好きだ:ノードごとにcpuset.cpusとcpuset.memsを定義し、CPUAffinity=やNUMAMask=などのsystemdパラメータでサービスを開始する。バッチプロセスやセカンダリプロセスは、レイテンシが重要な層のコアに入らないように、プールを分けています。繰り返し実行されるジョブについては、コアが空いている時間帯に正確に起動するよう計画している。.
割り込みとI/Oの親和性
アプリのスレッドに必要なのは局所性だけではない。 割り込み とI/Oパスをノードの近くに配置した:
- ネットワーク:NICのRX/TXキューを同じNUMAノードのコアにバインドし(RSS/XPSを設定)、パケット処理とアプリのスレッドがキャッシュとRAMのローカリティを共有するようにする。.
- ストレージ:ノードごとにNVMeキューとIOスレッドをピン留めする。ホットボリュームがノードをまたがないようにblk-mqのキュー配分をチェックする。.
- irqbalance: 特別に設定するか、クリティカルキューでは無効にして smp_affinity を使って手動で設定する。.
オペレーティング・システムの機能の的を絞った利用
私は厳格なレイテンシープロファイルのために意図的にカーネルの機能を使用している:
- isolcpus/nohz_full/rcu_nocbs:一般的なスケジューリングからコアを切り離し、ティックの負荷を最小限に抑え、RCUコールバックを再配置する。.
- スケジューラポリシー:リアルタイムコンポーネントにはSCHED_FIFO/RRを控えめに使用する。.
- 自動NUMAバランシング:カーネルがメモリをシフトしないように、厳密にpinされたワークロードでは、しばしば非アクティブにされる。.
- Transparent Huge Pages: TLBのミスを減らすため、本当に大きなヒープには明示的なHuge Pagesを使用する。.
NUMAを意識したストレージポリシー
と一緒に ヌマクトル 優先的なローカルメモリアロケーションを強制したり、preferredやinterleaveといったポリシーを使用する。可能であれば、データベース・バッファ・プールのような大規模なインメモリ構造をノード内に保持する。メモリ要件が増加した場合は、リモートアクセスの増加を観察し、セグメンテーションやシャーディングによって対応します。チューニングに関する実践的な洞察は、私に以下のガイドラインを与えてくれる。 NUMAバランシング, それを負荷テストで確認する。こうすることで、メモリアクセス時間を低く抑え、予測しやすくすることができる。.
ストレージ技術:巨大ページ、ヒープ、ガベージコレクション
メモリー管理がP99のレイテンシーを決めることが多い。私は、大きくて長寿命のヒープが支配的な巨大ページ(DBバッファやJVMヒープなど)を使っている。これにより、TLBミスやページウォークを減らすことができる。JVMワークロードについては、ノードごとのヒープ・サイズに注意を払い、GCスレッドとヒープがローカルに残るようにNUMA最適化を有効にする。.NETとGoでは、GCとゴルーチン・プールを計画し、無秩序にノード間のコアを埋めないようにする。データベースでは、大きなバッファ・プールをノード・ローカル・セグメントに分割するか、ノードごとに複数の小さなインスタンスを実行する。.
実用的なホスティング:典型的なワークロード
データベース、キャッシュ、そして大規模なアプリケーションサーバーは、次のことに敏感に反応する。 CPUロカリティ とメモリ・レイテンシーが増加する。複数のNUMAノードに分散したVMは、コンピューティングとメモリーのパスを増やし、クエリーやAPIコールを遅くする。そのため私は、VMのvCPUが物理ノードに割り当てられ、メモリがそこに残るようにVMを配置している。コンテナ・プールには一貫したCPUセットが割り当てられ、ワーカーがノードを飛び越えることはない。このような配慮は、特に並列性の高いeコマースやAPIサービスで効果を発揮する。.
きめ細かなアプリ戦略
アプリケーション・レベルでは、局所性が維持されるようにノードを切り離す:
- ワーカー・プール:NUMAノードごとに1つのプールがあり、それぞれがノード間の通信を避けるためにローカルキューを持つ。.
- シャーディング:データとセッションをノードローカルに保つ。ホットシャードが複数のノードにまたがらないようにハッシュを選択する。.
- キャッシュ:集中型ではなく複製型。読者はノードローカルなコピーを好む。.
- ランタイムのスレッド固定化:ネットワークスタック(Nettyなど)やDBクライアントでは、ワーカーを固定コアにバインドし、IRQの近接性を観察する。.
モニタリングとトラブルシューティング
賢明なモニタリングは、全体的な稼働率以上のものを示す。 NUMA-効果はノードの詳細値に隠されています。私は、コアやノードごとのCPU負荷、ノードごとのメモリ使用率、リモートアクセス率を監視している。個々のコアがオーバーフローしているのに他のコアが未使用のままであれば、これはアフィニティの設定が悪いことを示しています。あるノードのRAMが満杯で、別のノードのRAMに予備がある場合は、メモリ・ポリシーや配置を調整する必要があります。私はこれらのシグナルを使ってボトルネックを客観的に記録し、次の変更を導き出す。.
| 指標 | 注釈/症状 | 典型的な原因 | 速いアクション |
|---|---|---|---|
| CPU/コア | 一部のコアは恒常的に高い | 誤ったピン留め | コアグループの再配分 |
| ノードあたりRAM | 限界のノード | メモリがローカルではない | セット・ナンバクトル・プリファード |
| リモートレート | 高いリモートアクセス | ノード経由のVM/コンテナ | バンドルvCPU/CPUセット |
| コンテキスト・スイッチ | 不規則な待ち時間 | スレッドハイク | ピン・アフィニティは難しい |
アンチパターンと典型的なつまずきブロック
私は、NUMAに関係なくグローバルCPUの制限は避けている。また、vCPUが多すぎる「1つの大きなVM」がリニアにスケールすることはほとんどありません。irqbalanceが制御されずに実行されると、I/Oの局所性が希薄になる。そして:バッファコアなしでハードにピニングしすぎると、メンテナンスとサイドロードを阻害する可能性がある。.
パフォーマンス効果を測定可能にする
の効果を測定する。 親和性 とNUMAの変更は、常に再現可能なベンチマークで行われます。同一のデータセットでビフォー・アフターを比較することで、透明性のある改善が示されます。合成テストと現実的な負荷プロファイルを組み合わせることで、最適化が日常的な使用で実を結ぶようにしています。P95レイテンシやP99レイテンシなどの主要な結果数値は、平均値よりも意味があることが多い。これにより、私は早い段階で決定を検証し、副作用を認識することができます。.
仮想化とコンテナ
ハイパーバイザーのセットアップでは vNUMA, ゲストVMが物理的なトポロジーを理解できるように。VMのvCPUを物理的に一致するノードにパックし、リモート・アクセスを最小限に抑える。コンテナについては、CPUセットが一貫性を保ち、トポロジー・マネージャーがノードのローカライズを尊重するように、CPUリクエストと制限を定義する。多くのvCPUを持つ大規模なVMをノード間でずらすのは、アプリケーションが内部セグメンテーションを許可している場合に限られる。ノードごとのレイテンシー、スループット、利用率に基づいて各配置を評価する。.
オーケストレーション:Cgroups、Kubernetesとその共同開発。.
コンテナでは、安定したCPUセットとmems割り当てを持つ保証クラスやバースト可能クラスに頼っている。single-numa-node」モードのトポロジー・マネージャーは、ポッドをノードローカルに保つのに役立つ。長時間稼働するリアルタイムパートでは、CPUマネージャーを「静的」モードで使ってコアを排他的に保つ。HugePagesをリクエスト/リミットとしてスケジューリングし、ワークロードの役割ごとにポッドをグループ化して、ノードが異質な過負荷にならないようにしている。重要:配置ルールが意図せず局所性を壊さないように、ノードラベルを適切に維持する。.
ホスティング・プロバイダーの役割
優れたプロバイダーは透明なサービスを提供する NUMAトポロジー, アフィニティ・オプションとノード・メトリクスの洞察。私は、ハイパーバイザーとオーケストレーションがNUMAを真剣に認識し、vCPUの配置が制御可能であることを確認します。ノードごとのCPU、RAM、リモートクォータを提供するモニタリングも重要です。これにより、どの程度厳密にピンを立てるか、どのようにメモリポリシーを設定するかを自分で決めることができます。このようなコントロールにより、要求の厳しいワークロードも信頼性が高く、予測可能なものになります。.
オペレーティング・モデル:安全な変更の導入
ピンニングとNUMAポリシーを反復的に導入します:最初にノードで、明確に定義されたロールバックステップで。再現性を確保するために、トポロジー、割り当て、カーネル・パラメーターを文書化しています。リリースの際には、カナリー・トラフィックを使用し、P95/P99、コンテキスト・スイッチ、リモート・レートを少なくとも1回の全負荷フェーズの間モニターし、その後で広くロールアウトします。こうすることで、改良を安定させ、リスクを管理しやすくすることができる。.
ベストプラクティスをコンパクトに
私はすべての最適化を、徹底的な取り組みから始める。 トポロジー解析 そして、コアとノードの割り当てを文書化する。その後、データベース、キャッシュ、アプリサーバーが別々のノードリソースを受け取るようにワークロードを分割します。グループサイズを微調整する前に、重要なプロセスをピン留めし、ローカルメモリを優先します。すべてのチューニングにベンチマークとノードメトリクスを適用し、効果を明確にします。成長については、ノードごとに計画を立て、モノリシックな巨大インスタンスを爆発させるのではなく、インスタンスをスリムに保ちます。.
まとめと次のステップ
ターゲットを絞って プロセスとの親和性 と本当のNUMAを認識することで、同じハードウェア上のワークロードを顕著に前進させることができます。明確な配置、ローカルメモリの割り当て、結果の一貫した測定が重要です。VMとコンテナをノードの近くにバンドルすることで、レイテンシーが短縮され、スループットが向上する。ホスト上でパイロット・プロジェクトを開始し、アフィニティとメモリ・ポリシーをテストし、最適な設定を採用することをお勧めする。こうすることで、新しいサーバーを購入することなく、パフォーマンスを段階的に向上させることができる。.


