手当たり次第に書くんだ

飽きっぽいのは本能

VM の virtio-net 性能設計 – vhost-net / multiqueue / queue を確認する

KVM / QEMU の VM では、virtio-net が標準的な仮想 NIC として使われます。ただし、virtio-net と vhost-net は置き換え関係ではありません。virtio-net は guest が使う仮想デバイス方式で、vhost-net は virtio の処理を host kernel で高速化する backend です。

この記事では、guest driver、virtqueue、QEMU または vhost-net、tap、Linux bridge / Open vSwitch、物理 NIC までの処理経路を確認します。その上で multiqueue、offload、CPU / NUMA 配置を測定し、vhost-user、SR-IOV、DPDK へ進む必要があるかを判断します。

virtio-net と backend を分ける

要素動作する場所役割
virtio-net driverguest OS仮想 NIC と virtqueue を guest へ提供する
virtqueueguest と host の共有領域packet descriptor と buffer 情報を受け渡す
QEMU backendhost userspacevirtio packet を QEMU process で処理する
vhost-nethost kernelvirtio dataplane の多くを kernel で処理する
vhost-userhost userspace dataplaneUnix socket と共有メモリで別 process へ接続する
tap / vnethost kernelVM interface を bridge や OVS へ接続する
bridge / OVShost networkVM、物理 NIC、overlay の転送を行う

libvirt では、<model type='virtio'/> が guest 側の device model、<driver name='vhost'/> が host backend を示します。driver 名を省略した場合、libvirt は利用可能なら vhost を使い、利用できなければ QEMU backend へ戻るため、実際の XML と host module を確認します。

packet の処理経路を確認する

構成主な経路確認する CPU
virtio + QEMUguest → virtqueue → QEMU → tap → bridge / OVS → NICvCPU、QEMU emulator、softirq
virtio + vhost-netguest → virtqueue → vhost-net → tap → bridge / OVS → NICvCPU、vhost thread、softirq
virtio + vhost-userguest → virtqueue → shared memory → userspace dataplane → NICvCPU、vhost-user、PMD、NUMA
SR-IOV VFguest → VF → physical NICvCPU、VF、IRQ、NUMA

同じ virtio-net でも backend と接続先によって処理経路が変わります。帯域だけでなく、packet rate、CPU 使用率、softirq、queue drop、retransmission、p95 / p99 latency を見ます。

VM の interface 定義を確認する

virsh domiflist vm01
virsh dumpxml vm01
virsh domifstat vm01 vnet0
virsh domstats vm01 --interface --vcpu --cpu-total
ip -s link show vnet0
bridge link show
lsmod | grep -E 'vhost|tun'
  • model が virtio になっているか
  • driver backend が vhost または qemu のどちらか
  • interface の target 名と host 側 tap / vnet の対応
  • 接続先が Linux bridge、OVS、macvtap、network のどれか
  • interface、vCPU、host CPU の統計を同じ時間帯で取得できるか

vhost-net と multiqueue の XML

次は Linux bridge へ接続する virtio-net interface で、host backend に vhost-net、queue 数に 4 を指定する例です。queue 数は例であり、vCPU 数、traffic flow、host CPU、NUMA、guest driver の対応を確認して決めます。

<interface type='bridge'>
  <mac address='52:54:00:12:34:56'/>
  <source bridge='br0'/>
  <target dev='vnet0'/>
  <model type='virtio'/>
  <driver name='vhost' queues='4'/>
</interface>

libvirt の queues は virtio-net multiqueue の queue 数を指定します。queue ごとに別 CPU で処理できる可能性がありますが、queue を増やすほど thread、interrupt、cache、設定の負荷も増えます。

guest で queue と offload を確認する

guest 側では、interface の channel 数、driver、offload、drop を確認します。interface 名は環境に合わせて変更します。

ethtool -i eth0
ethtool -l eth0
ethtool -k eth0
ethtool -S eth0
ip -s link show eth0
cat /proc/interrupts
mpstat -P ALL 1

ethtool -l で maximum と current の queue 数を確認します。XML で queue を増やしても、guest driver が複数 queue を利用しているとは限りません。RSS、flow 数、IRQ affinity、RPS / XPS、vCPU 数を合わせて確認します。

checksum、GSO、TSO、GRO などの offload は CPU 負荷を減らせます。一方、packet capture では wire 上より大きな packet に見えることがあります。トラブル時も一括で無効化せず、host と guest のどちらで変換されるかを切り分けます。

host の tap、bridge、softirq を確認する

ip -s link show vnet0
ip -s link show br0
bridge link show
bridge fdb show br br0
cat /proc/softirqs
cat /proc/interrupts
mpstat -P ALL 1
sar -n DEV 1
症状確認する場所判断
guest TX dropguest queue、driver、vCPUguest が送信処理に追い付いているか
vnet drophost tap / vnetbackend と host network の境界で詰まっているか
bridge / OVS drop仮想 switch転送、flow、queue、policy の問題か
物理 NIC dropNIC queue、ring、IRQhost uplink が処理に追い付いているか
単一 CPU が高負荷vCPU、vhost、softirqmultiqueue と affinity が偏っていないか
帯域は低いが CPU が高いpacket size と pps小 packet の packet rate が限界か

CPU / NUMA と queue を対応付ける

multiqueue の効果は、queue を処理する vCPU と host thread が実行できる CPU に依存します。NIC、host CPU、VM memory が別 NUMA node に分かれると、packet 処理が NUMA interconnect をまたぐ可能性があります。

  • VM の vCPU と host CPU affinity
  • guest queue と IRQ の CPU 分散
  • vhost thread または QEMU thread の CPU
  • 物理 NIC queue と IRQ affinity
  • VM memory と NIC が属する NUMA node
  • bridge / OVS や PMD thread の CPU 配置

性能測定の条件を固定する

条件記録する内容
trafficTCP / UDP、flow 数、packet size、接続方向
VMvCPU、memory、virtio queue、offload、guest kernel
hostbackend、bridge / OVS、CPU affinity、NUMA、NIC
resultthroughput、pps、p95 / p99、CPU、drop、retransmission
operationmigration、snapshot、monitoring、Firewall への影響

単一 TCP flow の結果だけで multiqueue を評価しないようにします。queue 分散を確認する場合は、複数 flow と複数 packet size を使い、host と guest の CPU・queue 統計を同時に記録します。

vhost-user、SR-IOV、DPDK へ進む条件

次の方式進む根拠増える制約
vhost-netQEMU backend の CPU 負荷を減らしたいkernel backend の確認と thread 配置
vhost-useruserspace switch / dataplane と接続したい共有メモリ、socket、NUMA、再接続
SR-IOV仮想 switch を迂回して低遅延・高 pps が必要物理 NIC、VF、IOMMU、移行性、監視
DPDK専用 userspace dataplane が必要専有 CPU、HugePages、PMD、NUMA、運用

virtio-net + vhost-net で要件を満たせるなら、可搬性、可観測性、Firewall、QoS、バックアップなど、仮想化基盤の機能を維持しやすくなります。高度な方式は性能の上位互換ではなく、処理場所と運用責任を変える選択です。

よくある誤解

誤解実際の確認
virtio-net を vhost-net に置き換えるvirtio guest device と vhost backend を組み合わせる
queue 数は vCPU 数まで増やせばよいflow、IRQ、CPU、NUMA、guest 対応を測定する
帯域が出ないので SR-IOV にするpps、single flow、CPU、drop、backend を先に確認する
offload は packet capture を壊すcapture 位置と segmentation / aggregation の段階を確認する
DPDK は virtio を使わないvhost-user と virtio guest driver を組み合わせる構成がある

まとめ

virtio-net は guest が使う仮想 NIC 方式で、host 側では QEMU backend、vhost-net、vhost-user などと組み合わせます。最初に device model、backend、tap、bridge / OVS、物理 NIC の処理経路を確定します。

その後で queue 数、offload、vCPU、vhost thread、softirq、NUMA を同じ測定条件で確認します。virtio-net + vhost-net で要件を満たせない根拠が得られた時に、vhost-user、SR-IOV、DPDK と、それに伴う移行性・監視・障害復旧の制約を比較します。

関連する記事
VM の virtio-net 性能設計 – vhost-net / multiqueue / queue を確認する

コメントを残す

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

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

トップへ戻る