なぜ「モンスター級」の仮想マシンが遅いのか?実例から学ぶ教訓
SQL Serverの仮想マシンに32 vCPUと128GBのRAMを割り当てたのに、なぜか動作がもっさりしている…そんな経験はありませんか?以前、私は奇妙なケースに遭遇しました。小規模なVMはサクサク動くのに、その「モンスター級」VMだけが極端にレスポンスが悪いのです。たとえ Windows 仮想マシンを「サクサク」に最適化する 設定を施していても、CPU ReadyやDisk Latencyを確認しても正常(グリーン)でしたが、実際にはパフォーマンスが30%も低下していました。原因は、NUMAトポロジ (NUMA Topology) の不一致でした。
物理ソケットの能力を超えるvCPUやRAMを持つ大規模な仮想マシン(Wide VM)を構築する場合、CPU一人に「すべての重荷」を背負わせないための設計が重要ですが、VMwareのデフォルト設定は必ずしも最適ではありません。ここで Virtual NUMA(vNUMA)を手動で調整し、本来のパフォーマンスを取り戻す必要があります。
NUMAを理解する:CPUにRAMを「借り」に行かせてはいけない
物理NUMAとは?
2枚のIntel Xeon CPUを搭載したサーバーを想像してください。各CPUは独自のRAM領域を直接管理しており、これをローカルメモリ (Local Memory) と呼びます。もしCPU 1がCPU 2側のRAMからデータを取得する必要がある場合、高速バス(IntelのUPIやAMDのInfinity Fabricなど)を経由しなければなりません。このリモートメモリ (Remote Memory) へのアクセスは、レイテンシ(遅延)を60nsから100ns以上に増大させ、アプリケーションのボトルネックとなります。
Virtual NUMA (vNUMA) の役割
vNUMAはこの物理構造を仮想マシン(Guest OS)内部に可視化します。これにより、WindowsやLinuxはどのCPUがどのRAM領域と紐付いているかを正確に把握できます。OSはプロセスを1つのノード内に収まるよう優先的に配置し、ソケットをまたいだRAMの「借り入れ」による遅延を防ぎます。
物理ホストのNUMA構成を確認する方法
推測ではなく、具体的な数値を確認しましょう。ホストにいくつのNUMAノードがあるか正確に知る必要があります。最も早い方法は、ESXiにSSHで接続してesxtopを入力し、mキーを押してメモリ情報を表示することです。
または、ESXi Shellで以下のコマンドを実行して素早くパラメータを取得します。
# ホスト上のNUMAノード数をカウント
esxcli hardware memory get | grep "NUMA Node Count"
# コアの割り当て詳細を確認
localcli hardware cpu list | grep "Node ID" | sort -u
例えばホストが2ソケットで、1ソケットあたり16コアの場合、2つの物理NUMAノードがあり、各ノードが16コアを保持していることになります。
実践:vNUMAを正しく設定するには?
デフォルトでは、VMwareは仮想マシンに9つ以上のvCPUが割り当てられた際にvNUMAを自動的に有効化します。しかし、このアルゴリズムはAMD EPYCのような複雑なチップレット構造を持つ最新CPUでは、時として最適に機能しないことがあります。
1. 「アライメント (Alignment)」のルール
重要なポイントは、仮想マシンの1つのvNUMAノードが、物理的な1つのNUMAノードに収まるようにすることです。
例えばホストが1ソケットあたり16コアの場合に20 vCPUのVMを作成すると、VMwareはVMを2つのvNUMAノードに分割せざるを得ません。この分割が不均等(例:4 vCPUのノード and 16 vCPUのノード)になると、パフォーマンスが不安定になります。
2. Cores per Socketの設定(vSphere 6.5以降の注意点)
以前は、エンジニアがvNUMAを強制するためにCores per Socketを調整するのが一般的でした。vSphere 6.5以降、VMwareは表示上のトポロジと内部のvNUMA構造を分離し、よりスマートになりました。最新のvSphereで仮想マシンを「息切れ」させないためにも、この設定がライセンス管理やトポロジに与える影響を理解しておくことは依然として非常に重要です。
- アドバイス:原則として
Cores per Socket = 1(デフォルト)のままにしてください。ソフトウェア側でソケット数の制限がある場合のみ変更し、そのコア数が物理ノードのコア数の約数になるように設定してください。
3. 詳細パラメータのチューニング
最適化の「魔術師」を目指すなら、Edit Settings > VM Options > Advanced > Edit Configurationから以下の2つのパラメータに注目してください。
numa.autosize.once = FALSE
デフォルトはTRUEで、VM作成時に一度だけvNUMAが計算されます。もしVMを異なる世代のCPUを搭載したホストへ vMotionさせた場合、vNUMAの不一致が発生します。これをFALSEに設定すると、起動するたびに新しいハードウェアに合わせて vNUMA を再計算するようになります。
numa.vcpu.preferHT = TRUE
ハイパースレッディング (Hyper-Threading) を活用して、大規模な仮想マシンをより少ないNUMAノードに詰め込みたい場合に使用します。例:24 vCPUのVMを16コア/32スレッドの物理ノード1つに収める。純粋な計算能力はわずかに低下する可能性がありますが、RAMのレイテンシは大幅に改善されます。
成果を確認する
再起動後、ゲストOSが意図通りに認識しているか確認しましょう。Linuxの場合はnumactl --hardwareコマンドを使用します。Windowsの場合は、SysinternalsのCoreinfoツールをダウンロードして実行します。
coreinfo.exe -n
vCPUが正しくグループ化され、RAMが各ノードに均等に割り当てられていれば成功です。
実戦経験:SAP HANAのケーススタディ
以前、AMD EPYC CPU上で動作する SAP HANA システムを担当したことがあります。当初、「Memory Slop」現象によりクエリの実行が非常に低速でした。AMDのL3キャッシュ数に正確に一致するようにnuma.nodeCountパラメータを調整したところ、クエリ処理速度が20%向上しました。素晴らしいのは、ハードウェアのアップグレードに一銭もかけずにこの結果を得られたことです。
結論
vNUMAの最適化は、小規模なVM(8 vCPU未満)には不要です。しかし、データベース、ERP、AI と VDI のためのリソース最適化が求められる大規模環境では、これは死活問題となります。vNUMA設定が物理構造に近いほど、レイテンシは低下し、アプリケーションはスムーズに動作します。システムの最適化、ぜひ成功させてください!
