手当たり次第に書くんだ

飽きっぽいのは本能

VM パフォーマンス最適化の進め方 – 計測、仮説、変更、再検証

VM パフォーマンス最適化は、CPU、memory、NIC を増やす作業ではありません。どの service indicator が要件を満たしていないかを定義し、guest、QEMU、host、storage、network のどこで仕事が止まっているかを計測し、仮説を 1 つずつ検証する作業です。

この記事では、個別の tuning 手順ではなく、baseline、failure domain、metric、変更、再測定、rollback を一つの workflow にします。CPU pinning、HugePages、IOThread、multiqueue、SR-IOV、DPDK などは、原因と成功条件が明確になった後で選びます。

最適化の前に SLO と workload を定義する

性能要件を CPU 使用率ではなく、利用者または system が必要とする結果で定義します。同じ VM でも、batch completion time を重視する場合と、request の p99 latency を重視する場合では、採用する変更が異なります。

workloadservice indicator条件
Web / APIrequest rate、p95 / p99、error rate同時接続、payload、cache hit
databasetransaction rate、query latency、lock waitdataset、read / write 比率、durability
batchcompletion time、throughput、retryinput size、worker 数、deadline
NFVpps、throughput、drop、jitterpacket size、flow 数、feature set
storageIOPS、bandwidth、fsync latencyblock size、queue depth、read / write 比率
  • 正常と判定する SLO と許容差
  • 通常、peak、障害縮退の workload profile
  • 測定時間、warm-up、sample 数
  • 同時に動く VM、backup、batch、migration
  • 成功条件と rollback 条件

guest から physical resource まで経路を描く

metric を集める前に、VM の処理が通る resource path を確認します。guest で見える device 名と、libvirt target、QEMU thread、host device、backend volume、physical NIC を対応付けます。

resourceguestvirtualizationhost / backend
CPUprocess、run queue、stealvCPU thread、emulator、quotapCPU、SMT、NUMA、co-tenant
memoryworking set、fault、swapballoon、HugePages、numatuneNUMA node、reclaim、KSM
storagefilesystem、block queuevirtio、QEMU block、IOThreadfilesystem、LVM、Ceph、NVMe
networksocket、virtio-net、queuetap、vhost、bridge、OVSNIC、IRQ、switch、tunnel

この対応がないまま host の高負荷 process や device を見ても、対象 VM の workload と関係があるか判断できません。最初に name、ID、interface、disk target、NUMA node を結びます。

baseline は同じ時間窓で採取する

正常時と問題発生時を比較できるよう、guest と host の clock を同期し、同じ開始時刻、間隔、継続時間で metric を採取します。counter は累積値を含むため、区間差分を使います。

date --iso-8601=seconds
uptime
vmstat 1
mpstat -P ALL 1
iostat -xz 1
ip -s link
cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io

Linux の Pressure Stall Information は、CPU、memory、I/O の不足で task が止まった時間を示します。utilization が低くても pressure が増えていれば、別 resource を待って仕事が進んでいない可能性があります。

utilization、pressure、queue、latency を分ける

metric答えること単独で判断できない理由
utilizationresource が使われた割合高くても SLO を満たす場合がある
pressureresource 不足で task が止まった時間どの process が影響を受けたかを追加確認する
queue処理待ちの仕事量短い spike は平均値に埋もれる
latency完了までの時間throughput と workload 条件が必要
throughput単位時間の完了量latency と error を犠牲にしていないかを見る
error / drop完了できなかった仕事retry により負荷を増やす場合がある

平均 CPU、平均 latency、平均 bandwidth だけで合否を決めません。p95 / p99、最大 queue、PSI total の増分、drop、retry を同じ graph または時刻表で比較します。

libvirt で VM と QEMU の統計を取得する

virsh domstats は、domain の CPU、vCPU、memory、block、interface、IOThread、perf などの統計 group を取得できます。hypervisor や domain state によって未提供の field があるため、欠損を 0 とみなしません。

virsh domstats vm01 --state --cpu-total --balloon --vcpu --interface --block --perf --iothread --memory
virsh vcpuinfo vm01 --pretty
virsh vcpupin vm01
virsh emulatorpin vm01
virsh numatune vm01
virsh domblklist vm01 --details
virsh domiflist vm01
virsh dumpxml vm01

vcpu.<num>.wait や delay、block の read / write time、interface counter など、利用できる field を区間差分で比較します。XML の設定値と実行時 counter を分け、設定があることだけで効果を断定しません。

failure domain を比較して対象範囲を狭める

発生範囲優先して確認する層
1 processapplication、lock、GC、connection pool
1 VMguest kernel、virtual device、VM XML、QEMU
同じ host の複数 VMpCPU、NUMA、host I/O、NIC、co-tenant
同じ storage の複数 hoststorage network、volume、controller、rebuild
同じ network pathbridge、OVS、firewall、tunnel、uplink
基盤全体shared service、capacity、変更、外部 dependency

正常な VM、別 host、別 storage、別 network path と比較すると、変更せずに仮説を減らせます。個別 VM の tuning は、failure domain を確認した後に行います。

仮説は原因、根拠、反証条件を一組にする

仮説根拠反証条件
pCPU contentionvCPU wait、steal、host run queue が同時に増えるhost に余力があり wait も増えていない
NUMA remote accessCPU placement と memory node が離れ、remote counter が増えるlocal placement でも同じ latency
storage saturationguest と backend の queue / latency が同時に増えるbackend latency が正常で QEMU だけ待つ
network queue dropthroughput 頭打ち時に queue と drop が増える全 interface の drop が増えていない
memory pressurereclaim、fault、swap、memory PSI が増えるworking set に余力があり pressure もない

仮説に反証条件がないと、変更後に都合のよい metric だけを見ることになります。改善するはずの indicator と、悪化してはいけない indicator を先に決めます。

標準構成から段階的に制約を追加する

最初から passthrough や DPDK を選ばず、標準構成が SLO を満たすか確認します。性能を上げるために abstraction を減らすほど、migration、snapshot、sharing、monitoring、failure recovery の制約が増えます。

段階選択肢追加される主な制約
標準共有 CPU、通常 page、virtioscheduler と shared backend の競合
配置制御CPU pinning、numatune、HugePagescapacity、NUMA、移行先互換
処理分離IOThread、multiqueue、vhost-userthread / queue affinity と監視
device 直結SR-IOV、PCI Passthroughmigration、sharing、host visibility
専用 dataplaneDPDK、poll modeCPU 専有、HugePages、運用 tool

上位段階が常に優れているわけではありません。必要な SLO を満たす最小の制約を選びます。

変更は 1 つずつ再検証する

段階実施すること
1SLO、workload、failure domain、baseline を記録する
2metric から原因候補と反証条件を決める
3XML、host 設定、application 設定の変更点を 1 つにする
4同じ workload、時間、sample 数で再測定する
5成功 indicator と副作用を比較する
6改善しなければ戻し、次の仮説へ進む

CPU pinning、HugePages、queue 数、cache mode を同時に変えると、因果関係を追えません。変更に依存関係がある場合は、適用順序と各段階の測定点を決めます。

測定の再現性を確保する

  • warm-up と本測定を分ける
  • 同じ dataset、request、packet、block size を使う
  • background job と co-tenant の条件を記録する
  • 平均だけでなく分位点と sample 数を残す
  • host、guest、backend の version と設定差分を保存する
  • 複数回実行し、ばらつきと confidence を確認する

短い benchmark の最高値を採用せず、実運用に近い継続時間と peak 条件で比較します。低遅延 workload では、平均 throughput を維持していても p99 と jitter が悪化すれば不合格です。

performance result を decision record に残す

記録項目内容
目的改善する SLO と business / service 上の理由
baselineworkload、metric、時間、topology、version
仮説原因、根拠、反証条件
変更XML、host、guest、application の差分
結果成功 indicator、副作用、ばらつき
判断採用、保留、rollback と次の action

結果だけでなく、採用しなかった理由も残します。将来 hardware、kernel、QEMU、workload が変わった際に、再評価すべき前提が分かります。

rollback を性能試験の一部にする

変更前の live / inactive XML、host topology、pool、affinity、queue、cache、network path を保存します。rollback 後に設定が戻っただけでなく、baseline の性能と運用機能を再現できるか確認します。

virsh dumpxml vm01
virsh dumpxml vm01 --inactive
virsh domstats vm01 --cpu-total --balloon --vcpu --interface --block --iothread --memory
virsh vcpupin vm01
virsh emulatorpin vm01
virsh numatune vm01
lscpu -e=CPU,NODE,SOCKET,CORE,ONLINE
numactl --hardware
  • p99、throughput、error が閾値を超えた場合の rollback
  • VM 起動、restart、migration が失敗した場合の rollback
  • 同居 VM や host service が悪化した場合の rollback
  • 設定変更と workload 変更を別々に戻せること
  • rollback 後の再測定を予定に含めること

よくある失敗

失敗問題修正
CPU 使用率だけで判断するI/O wait と pressure を見落とすlatency、queue、PSI を合わせる
問題発生後だけ測る正常 baseline がない継続的に同じ metric を保存する
guest だけを見るhost と backend の競合を見落とすresource path を対応付ける
複数設定を同時に変える効果と副作用を分離できない1 変更 1 再測定にする
最高値だけ採用するばらつきと tail latency を隠す複数回と分位点で比較する
速くなれば完了にするmigration と recovery を失う運用 lifecycle も test する

まとめ

VM パフォーマンス最適化は、個別の高速化技術を積み上げる作業ではありません。SLO と workload を定義し、guest から physical resource までを同じ時間窓で測り、utilization、pressure、queue、latency、throughput、error を対応付けます。

原因候補には根拠と反証条件を持たせ、変更を 1 つだけ適用して再測定します。改善量だけでなく migration、sharing、monitoring、recovery の制約と rollback を確認し、必要な SLO を満たす最小の変更を採用することが要点です。

関連する記事
VM パフォーマンス最適化の進め方 – 計測、仮説、変更、再検証

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る