手当たり次第に書くんだ

飽きっぽいのは本能

VM の性能ボトルネックを見分ける – guest / host / backend の切り分け

VM の性能低下は、guest OS の CPU 使用率だけでは特定できません。guest、QEMU、host kernel、storage backend、network datapath が重なり、ある層の待ち時間が別の層の高負荷に見えることがあります。

この記事では、CPU、メモリ、storage I/O、network I/O の症状を入口に、どの層で仕事が進まず待たされているのかを切り分けます。最初に観測時間をそろえ、次に guest と host を対応付け、最後に変更を 1 つずつ試します。

ボトルネックは利用率ではなく待ち時間で見分ける

utilization が高い資源は候補ですが、高いだけで原因とは限りません。CPU が高くても処理量が伸びていれば正常な場合があり、CPU が低くても memory や I/O を待って仕事が進んでいない場合があります。

指標意味注意点
utilization資源が使われた割合高いことと、待ち時間の原因であることは同じではない
queue処理を待つ仕事の量短い spike は平均値に埋もれる
latency完了までに要した時間平均値だけでなく p95 / p99 を見る
throughput単位時間に完了した仕事latency と同時に比較する
pressure資源不足で task が止まった時間CPU、memory、I/O の PSI を分ける
error / drop処理できなかった仕事再送や retry が負荷を増やす場合がある

Linux の Pressure Stall Information は、CPU、memory、I/O の競合で task が止まった時間を /proc/pressure/ から確認できます。単純な使用率とは違い、資源不足が workload の進行を妨げたかを見る指標です。

最初に症状と観測時間を固定する

調査前に、遅い操作、発生時刻、継続時間、対象 VM、比較対象、期待値を記録します。guest と host の統計を別の時刻に取ると、同じ事象を比較できません。時刻同期を確認し、同じ負荷区間で採取します。

  • どの request、batch、packet flow、disk operation が遅いか
  • 常時遅いのか、peak 時だけ遅いのか
  • 単一 VM だけか、同じ host の複数 VM に出るか
  • 変更前の正常時と比べて何が増えたか
  • p95 / p99 latency、throughput、error rate の期待値はいくつか
  • migration、snapshot、backup、deploy と発生時刻が重なっていないか

guest 側で症状の入口を確認する

guest では workload に近い指標から確認します。CPU、run queue、memory、swap、block device、interface、PSI を同じ時間帯で採取し、どの資源の待ちが増えたかを見ます。

uptime
vmstat 1
mpstat -P ALL 1
iostat -xz 1
free -h
ip -s link
cat /proc/pressure/cpu
cat /proc/pressure/memory
cat /proc/pressure/io
guest の所見次に疑うものまだ断定できない理由
run queue が長いvCPU 不足、steal、CPU quotahost の pCPU 競合でも同じ症状になる
swap / major fault が増えるguest memory 不足ballooning や host memory pressure も確認が必要
disk await が増える仮想 disk または backendQEMU queue、host filesystem、storage 装置を通る
network drop が増えるguest queue、vhost、bridge、NICdrop した層を interface ごとに追う必要がある
PSI が増える該当資源の競合system 全体か対象 process / cgroup かを分ける

VM と host の対応を確認する

guest の所見を host の VM 統計へ対応付けます。libvirt の domstats は domain の CPU、vCPU、memory、interface、block、I/O thread などをまとめて取得できますが、hypervisor が提供しない field は表示されません。

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

domstats の counter は累積値を含むため、1 回の値だけで判断しません。同じ間隔で 2 回以上取得して差分を計算し、guest の負荷区間と対応付けます。disk target と interface target は domblklistdomiflist で確認します。

CPU は busy、steal、run queue を分ける

症状guest で見るものhost で見るもの
vCPU が常に busyuser / system、thread 数、throughputpCPU 使用率、vCPU thread、CPU affinity
CPU は低いが遅いI/O wait、PSI、lock waitstorage / network latency、QEMU thread
steal が増えるsteal と p99 latencyCPU overcommit、同居 VM、run queue
一部 vCPU だけ高いsingle thread、IRQ、queuepinning、SMT sibling、NUMA node
負荷時だけ揺らぐrun queue と tail latencyco-tenant、IRQ、emulator thread

vCPU を増やす前に、workload が並列化できるか、host に物理 core の余力があるか、NUMA node をまたがないかを確認します。vCPU の追加は、CPU 競合や lock contention を増やす場合があります。

メモリは容量、配置、回収を分ける

空き memory が少ないだけでは不足とは限りません。guest の swap、major fault、memory PSI に加え、host の NUMA remote access、ballooning、KSM、HugePages、page reclaim、OOM を確認します。

確認すること
guestavailable memory、swap in / out、major fault、memory PSI
libvirtballoon current / maximum、NUMA policy、memory backing
hostnode ごとの空き memory、NUMA miss、reclaim、swap、OOM
HugePagespage size、node ごとの予約量、free pages、起動失敗
workloadcache、heap、working set、GC pause

CPU を node 0 に固定し、guest memory が node 1 に多く配置されている場合は、容量に余裕があっても remote access が増えます。CPU affinity と memory policy を同じ topology 上で確認します。

ストレージ I/O は経路ごとに latency を追う

guest filesystem から physical storage までには、仮想 block device、QEMU、host page cache、host filesystem、logical volume、network storage、storage controller などがあります。guest の await だけで disk 本体を原因と断定しません。

主な確認項目
guestqueue depth、await、utilization、filesystem、sync write
QEMU / libvirtblock counter、I/O thread、cache mode、discard
hostdevice await、queue、page cache、filesystem、thin pool
backendvolume latency、controller queue、network latency、snapshot
operationbackup、migration、trim、scrub、rebuild との競合

raw と qcow2、virtio-blk と virtio-scsi、cache mode、io_uring は、機能と経路を変える設定です。測定前に方式を変更すると、原因調査と tuning が混ざります。まず現在の経路で遅延が増えた層を特定します。

ネットワーク I/O は drop した場所を追う

network throughput が伸びない場合は、guest virtio-net、tap、vhost、bridge または Open vSwitch、physical NIC の順に packet と drop を追います。TCP retransmission が増えている場合は、CPU 不足や queue drop が network latency として見えている可能性もあります。

ip -s link
ethtool -S enp1s0
ss -s
cat /proc/net/softnet_stat
cat /proc/interrupts
virsh domifstat vm01 vnet0
  • guest と host の interface counter を同じ時間窓で比較する
  • RX / TX queue 数と vCPU 数の対応を確認する
  • softirq が特定 CPU に偏っていないか確認する
  • MTU、offload、multiqueue、RSS の前提を記録する
  • bridge、firewall、tunnel、software switch の処理を確認する
  • SR-IOV や passthrough では host から見えない範囲を明記する

複数 VM に出るかで故障範囲を絞る

発生範囲優先して確認する層
1 process だけapplication、lock、GC、connection pool
1 VM 全体guest kernel、仮想 device、VM 設定、QEMU thread
同じ host の複数 VMpCPU、NUMA memory、host I/O、NIC、同居 workload
同じ storage の複数 hoststorage network、volume、controller、backend operation
同じ network path の複数 VMswitch、firewall、tunnel、uplink、physical NIC
基盤全体共有 service、capacity、変更作業、外部 dependency

故障範囲を広げる比較は、個別 VM の設定変更より先に実施できます。正常な VM、別 host、別 storage、別 network path と比較すると、調査対象の層を減らせます。

変更は 1 つずつ同じ負荷で比較する

段階実施すること
1症状、SLO、発生時刻、対象範囲を記録する
2guest、libvirt、host、backend を同じ時間窓で測定する
3利用率、queue、latency、throughput、pressure を対応付ける
4原因候補と、反証できる指標を 1 組にする
5設定を 1 つだけ変更し、同じ workload で再測定する
6改善しない場合は戻し、次の仮説を試す

CPU pinning、HugePages、cache mode、multiqueue、SR-IOV、DPDK を同時に適用すると、どの変更が効いたのか分かりません。変更前の XML と測定値を保存し、成功条件とロールバック条件を先に決めます。

よくある誤判断

誤判断見落とすこと確認方法
CPU 100% だから vCPU を増やす並列性、steal、lock、host capacitythroughput と run queue を同時に見る
free memory が少ないから不足page cache と reclaimavailable、swap、fault、PSI を見る
guest の await が高いから disk 故障QEMU と backend の queue経路ごとの latency を比較する
network が遅いから NIC を交換softirq、queue、drop、retransmissioninterface ごとの counter を追う
平均値が正常だから問題なし短い stall と tail latencyp95 / p99 と PSI total の差分を見る
tuning を全部入れて比較因果関係と rollback1 変更 1 測定を守る

まとめ

VM の性能ボトルネックは、guest OS の中だけでは判断できません。症状と時間窓を固定し、guest、QEMU、host、storage、network の counter と latency を対応付けることで、待ち時間が発生した層を絞れます。

利用率だけでなく queue、latency、throughput、PSI、error / drop を一緒に見ます。その後で変更を 1 つだけ適用し、同じ workload で再測定します。この順序を守ると、高速化設定を増やす前に、本当に制約になっている資源を特定できます。

関連する記事
VM の性能ボトルネックを見分ける – guest / host / backend の切り分け

コメントを残す

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

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

トップへ戻る