手当たり次第に書くんだ

飽きっぽいのは本能

VM パフォーマンス Day6: ネットワーク最適化 – vhost-net / vhost-user

はじめに

前回(Day5)では、virtio-net が仮想 NIC の標準でありながら、パケット処理が QEMU に集中し、ユーザー空間とカーネル空間の往復(context switch)が性能上の大きな壁になることを整理しました。

今回は、この課題に対処するために生まれた以下の 2 つの高速化方式を解説します。

  • vhost-net:処理をカーネル側へ寄せる方式(kernel offload)
  • vhost-user:処理をユーザー空間に寄せる方式(user-space offload)

どちらも virtio の仕組みを基盤にしていますが、高速化のアプローチは大きく異なります。これらを理解することで、「virtio の高速化パス」の体系がはっきり見えてきます。

virtio-net の限界(Day5 の振り返り)

virtio-net では、パケットは次の経路をたどります。

VM(virtio-net)→ QEMU(ユーザー空間)→ ホストカーネル → NIC

この構造には次のボトルネックがあります。

  • QEMU スレッドに負荷が集中する
  • context switch が多く、レイテンシが増える
  • PPS(packet per second)が増えると急激に頭打ちになる

これらの課題に対処するために vhost-netvhost-user が登場します。

vhost-net:virtio をカーネルへ寄せる高速化

vhost-net の構造

vhost-net は、virtqueue の処理を QEMU からカーネルスレッド(vhost thread)へ移す 仕組みです。

VM → virtio-net → vhost thread(カーネル)→ NIC

QEMU が行っていた virtqueue の読み書きをカーネル側が担当するため、次の効果が得られます。

  • QEMU の負荷が大幅に減る
  • context switch が減少
  • 割り込み処理が効率化
  • PPS が安定しやすくなる

実際、10GbE クラスでも vhost-net を有効化するだけで数割の性能改善が見られます。

それでも残る制約

vhost-net は「virtio をカーネルに寄せただけ」であり、データパス自体は従来どおりホストカーネルを通ります。

ホストカーネルには以下の処理レイヤが存在します。

  • Linux ネットワークスタック
  • softirq
  • qdisc
  • Linux bridge / OVS(kernel datapath)

つまり、Linux カーネルという構造そのものがボトルネックになるケースでは、vhost-net でも限界があり、この壁を超えるために生まれたのが vhost-user です。

vhost-user:virtio をユーザー空間に寄せる高速化

vhost-user の構造

vhost-user は、virtqueue のメモリ情報を UNIX ドメインソケット経由でユーザー空間アプリケーションへ公開する方式です(ソケットは制御メッセージの交換だけに使われ、実際のパケットバッファは共有メモリ上で読み書きされます)。

典型的な構成:

VM → virtio-net → vhost-user backend(ユーザー空間)→ NIC(DPDK PMD)

QEMU は「virtqueue セットアップ」だけを担当し、データパスからは完全に退場します。

kernel bypass(カーネル回避)

vhost-user の最大の利点は、Linux カーネルのネットワークスタックを完全に回避できる点です。

DPDK の Poll Mode Driver(PMD)により、以下を実現します。

  • 割り込みを使わない
  • context switch がほぼゼロ
  • メモリコピーが最小化
  • NUMA ローカリティを最大活用

そのため、以下の要件では vhost-user を採用するケースがよくあります。

  • NFV(仮想ルーター/FW)
  • 25GbE/40GbE/100GbE の高速パケット処理
  • 大量 PPS が要求される処理

vhost-user の重要な注意点

vhost-user は DPDK 必須ではない

仕様上、vhost-user backend は「ユーザー空間アプリ」であれば自由に実装できるため、DPDK が絶対条件ではありませんが、以下の理由から、DPDK を使わない vhost-user は 性能的に vhost-net を越えられません。

  • Linux カーネルスタックが残る
  • PMD thread なし
  • hugepage なし
  • kernel bypass できない

DPDK が使えない環境ではどうなる?

hugepage・PMD thread が使えない環境では、ユーザー空間高速化(kernel bypass)がそもそも不可能です。この場合、virtio 系の最大性能は vhost-net になります。

vhost-user(DPDKなし)は性能向上の意味が薄く、構成の複雑さだけが増えてしまいます。

つまり、vhost-user が本領を発揮するのは「DPDK + PMD thread」とセットの場合であり、それ以外では vhost-net が適切な選択肢となり、それ以上は SR-IOV となります。

virtio-net / vhost-net / vhost-user の比較

項目virtio-net(標準)vhost-net(kernel offload)vhost-user(user-space offload)
処理主体QEMU(ユーザー空間)カーネル(vhost thread)ユーザー空間(DPDK/OVS-DPDK など)
QEMU 負荷最大大幅に減少ほぼゼロ
データパスQEMU → カーネルカーネル内ユーザー空間内(DPDK PMD 等)
kernel bypassなしなしあり(DPDK 使用時)
割り込み多い(virtqueue 処理も QEMU)減るが存在基本ゼロ(polling)
context switch多い減少最小
必要要件特になし特になしhugepage / CPU pinning(DPDK 時)
ネットワーク制御(帯域制限/ACL)カーネル/OVS 依存カーネル/OVS 依存基本使えない(DPDK 側で実装)
最大 PPS低~中非常に高い(数倍以上)
DPDK 必須?もちろん不要不要仕様上不要だが、性能目的では実質必須
適用例ほとんどの汎用 VM高負荷な汎用 VM、一般サーバーNFV、vRouter、OVS-DPDK、高速パケット処理
DPDK不可環境での最適解標準最適解利点ほぼなし
  • virtio-net → vhost-net は同じアーキテクチャ内での高速化と言えます。互換性を保ったまま性能を底上げする、保守性の高い改善策です。
  • vhost-user はアーキテクチャそのものが別物になります。性能は圧倒的ですが、構築と運用が別世界であり、NFV 専用の特殊解とも言えます。

まとめ

vhost-net と vhost-user は、virtio-net の高速化を実現するための重要な技術ですが、適用領域がまったく異なります。

vhost-net

  • QEMU の負荷を大幅に削減
  • 従来構成をほぼそのまま高速化
  • DPDK 不可環境では virtio の最適解

vhost-user

  • データパスをユーザー空間へ移し、kernel bypass を実現
  • 最大性能を引き出すには DPDK が実質必須
  • 高 PPS・高速 NIC(25GbE〜)では必須のアプローチ

次回(Day7)は、virtio を高速化するもう一つのアプローチであるSR-IOV / PCI Passthrough を整理します。

VM パフォーマンス Day6: ネットワーク最適化 – vhost-net / vhost-user

コメントを残す

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

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

トップへ戻る