NUMAアーキテクチャの基本やUMAとの違い、パフォーマンス低下の仕組みをわかりやすく解説します。サーバー設計や仮想化環境で陥りやすい課題、NUMAが有効に働くシナリオも紹介。現代サーバー管理者が知っておくべきNUMAの注意点と最適化のポイントが分かります。
近年のサーバーは、すべてのリソースに均等にアクセスできる「大きなコンピュータ」ではなくなっています。CPUコア数の増加やマルチソケット構成の普及、プロセッサトポロジーの複雑化により、メモリへのアクセス速度が計算スレッドごとに異なる時代となりました。ここで登場したのがNUMAアーキテクチャ(Non-Uniform Memory Access)です。本来はサーバーの性能をスケーラブルに拡張するための設計ですが、実際にはシステムのパフォーマンスを低下させてしまうことも少なくありません。
NUMAとは、プロセッサコアから物理的な距離によってメモリアクセス速度が変化するコンピュータアーキテクチャです。従来のUMA(Uniform Memory Access)では、すべてのコアが同じメモリコントローラを経由して均等なレイテンシでRAMにアクセスしていました。しかし、コア数やメモリ容量が増大するにつれ単一メモリコントローラがボトルネックとなり、拡張性が制約されるようになりました。
NUMAでは、システムを複数のノードに分割し、それぞれのノードがプロセッサ(またはコア群)とローカルメモリを持ちます。自身のノードのメモリには高速でアクセスできる一方、他ノードのメモリにはプロセッサ間バスを経由するため遅延が発生します。この仕組みが多プロセッサ構成のサーバーで標準となっています。
UMAとNUMAの違いは単なる設計上の違いではなく、サーバーのメモリアクセスモデルそのものを変えます。UMAは単一ソケットや小規模なシステムに最適で、設計もシンプルかつ予測可能です。一方、NUMAではメモリがノードごとに分散され、ローカルアクセスは高速ですが、リモートアクセスには追加の遅延が発生します。特にサーバー用途では、応答時間の安定性が重要なため、この差が致命的になることもあります。
UMAでは負荷が上がるにつれて徐々に遅くなりますが、NUMAではスレッドやデータの配置が変わった瞬間にパフォーマンスが急激に低下する場合があります。複数ソケットを用いるサーバーでは、NUMAは避けられない選択肢となりましたが、予測しやすい動作を損なうリスクも抱えます。
NUMAシステムでは、各CPUコアが自分専用のNUMAノードに直結し、ノード内のローカルメモリには高速にアクセスできます。しかし、データが他ノードに配置されている場合、プロセッサ間バス(QPIやUPIなど)を経由する必要があり、アクセス速度が大きく低下します。
プログラムコードからはローカル/リモートの区別が見えないため、実際のタイミングや遅延はアプリケーションや管理者からは分かりにくくなっています。OSはスレッドとメモリの配置を最適化しようとしますが、スレッド移動や負荷変動でローカリティが失われやすいのが現実です。
NUMAはCPUの物理トポロジーと密接に関係しています。多ソケット構成ではそれぞれが独立したNUMAノードとなり、高速だが帯域や遅延に制約のあるバスで相互接続されます。さらに、最近のCPUはチップレット構造を採用し、1つのソケット内でも複数のNUMAドメインが存在し得ます。
このような構造では、OSやアプリケーションが物理トポロジーを正しく認識し、スレッドやメモリの配置を意識的に管理しなければ、リソース追加がむしろ性能低下を招くこともあります。
NUMAによるパフォーマンス低下の主因はデータローカリティの喪失です。スレッドとデータが異なるNUMAノードに配置されると、アクセスごとに遅延が発生し、CPUのアイドルタイム増加やIPC低下などが起こります。
また、複数スレッドが同時にリモートノードのメモリへアクセスすると、プロセッサ間バスの帯域がボトルネックとなり、全体のレイテンシが急増します。OSのスケジューラもCPU負荷の均等化を優先するため、NUMAローカリティを損なうケースが多く見られます。
特にスレッド数が多く、共有メモリを多用するシステムではこの傾向が顕著です。加えて、パフォーマンス低下が突発的かつ予測しづらいため、問題の特定や対策が非常に難しくなります。
1ソケットのシステムでもNUMAによる不安定さは発生しますが、マルチソケットサーバーではその影響が一層顕著です。ノード数の増加とともに、リモートアクセスの経路や競合も複雑化し、プロセッサ間バスが新たなボトルネックとなります。
仮想化環境では、複数のサービスやVMがNUMAノードをまたいで動作し、データやスレッドの局所性が維持しにくくなります。加えて、同期処理やロック、アトミック操作のたびにキャッシュラインの移動が発生し、ping-pong効果と呼ばれるレイテンシ増加が起こりやすくなります。
NUMAシステムでは、ローカルメモリアクセスは高速で安定していますが、リモートアクセス時にはプロセッサ間バスや他ノードのメモリコントローラを経由するため、数十ナノ秒単位で遅延が積み上がります。サーバーアプリケーションは並列スレッドや大量のリクエストを処理するため、微細なレイテンシも全体の応答時間やスループットに大きな影響を与えます。
特に同期処理が多いシステムでは、クリティカルなデータがリモートノードに置かれていることで待機時間が増え、全体のパフォーマンスを著しく低下させる要因となります。
NUMAは常に「悪」ではありません。計算とデータのローカリティが厳密に保てるワークロード(HPC、科学計算、レンダリング、明確に分割可能な分析処理など)では、NUMAの利点を最大限活かせます。また、大規模DBやインメモリ処理でも、NUMAノードごとにデータとスレッドを厳密に割り当てれば効果的です。
一方で、汎用的なサーバーワークロード(Webサービス、メッセージブローカー、マイクロサービス基盤、同期処理が多いシステムなど)はNUMAの遅延や不安定性に弱く、パフォーマンスが予測しづらくなります。仮想化やコンテナ環境では、リソースの競合やローカリティの喪失が顕在化しやすいです。
特に、ミニマムかつ安定したレイテンシが求められる用途では、NUMA由来のレスポンスのばらつきが大きな問題となります。
NUMAアーキテクチャは、現代のマルチソケットサーバーにとって不可避な進化の結果です。しかし、その複雑さは新たな問題(見えにくい遅延・不安定性・パフォーマンス低下)を生み出しました。NUMAによって、メモリが均等なリソースではなくなり、アクセス時間がCPUトポロジーやデータ配置、スケジューラ挙動に強く依存するようになっています。
特に仮想化やマイクロサービス、共有メモリ型DB、高度な同期処理を持つ環境では、NUMAを無視することが致命的なパフォーマンス劣化につながります。一方、データとスレッドのローカリティを明確に制御できれば、NUMAは多ソケット構成の真価を発揮します。
結局のところ、NUMAはハードウェアからソフトウェアへの責任転嫁とも言えます。サーバーの規模が大きくなればなるほど、NUMAの理解と適切な制御が安定したパフォーマンス維持のために不可欠です。現代のサーバー運用において、NUMAへの対応はもはや避けられない知識となっています。