手当たり次第に書くんだ

飽きっぽいのは本能

KVM の io_uring はどれだけ効くのか – QEMU ストレージ I/O の検証

KVM / QEMU のストレージ I/O では、ゲスト OS 側のアプリケーションだけでなく、ホスト側の QEMU がどの I/O backend を使うかも性能に影響します。

この記事では、ゲスト OS 側の fio は libaio のまま固定し、ホスト側 QEMU の disk driver に io_uring を指定した場合と指定しない場合を比較します。つまり、ゲストアプリケーションではなく QEMU のストレージ I/O 経路を変えた検証です。

結論として、この検証環境では 4KB randread / iodepth 32 の条件で IOPS と帯域が約 15% 改善し、p50 から p95 のレイテンシも低下しました。ただし、これは単一環境での結果であり、QEMU、kernel、ストレージ backend、ディスク形式、I/O パターンによって効果は変わります。

io_uring とは何か

io_uring は Linux kernel が提供する非同期 I/O の仕組みです。ユーザー空間とカーネル空間の間に submission queue と completion queue を持ち、I/O 要求と完了通知を効率よく扱うことを目的としています。

KVM の文脈では、ゲスト OS のアプリケーションが io_uring を使うかどうかとは別に、QEMU がホスト側のストレージ I/O backend として io_uring を使うかどうかが問題になります。

観点今回の検証で固定したもの変更したもの
ゲスト OS 側fio は ioengine=libaio変更なし
仮想ディスクqcow2 / virtio変更なし
ホスト側 QEMUdisk driverio='io_uring' の有無
評価対象ゲスト内 fio の結果IOPS / BW / latency

QEMU で io_uring を有効化する

まず、ホスト側 kernel で io_uring が有効になっているかを確認します。

grep IO_URING /boot/config-$(uname -r)

次のように有効であれば、kernel 機能としては利用可能です。

CONFIG_IO_URING=y

libvirt の domain XML では、disk driver に io='io_uring' を指定します。io_uring を使わない場合は io 属性を付けない構成で比較しました。

io_uring 無効時

<driver name='qemu' type='qcow2'/>

io_uring 有効時

<driver name='qemu' type='qcow2' io='io_uring'/>

ここで重要なのは、ゲスト OS 側の fio を io_uring にしたわけではない点です。今回見ているのは、QEMU がホスト側でどの I/O backend を使うかによる違いです。

fio によるテスト条件

テストはゲスト OS 上で fio を実行し、4KB のランダムリードを 60 秒間行いました。

sudo fio --name=uringtest \
  --filename=/tmp/test.img \
  --size=4G \
  --rw=randread \
  --bs=4k \
  --iodepth=32 \
  --ioengine=libaio \
  --direct=1 \
  --numjobs=1 \
  --time_based=1 \
  --runtime=60 \
  --group_reporting
オプション意味
–rw=randread4KB ランダムリードを実行する
–bs=4k小さい I/O を高頻度に発行する
–iodepth=32同時に 32 個の I/O を発行する
–ioengine=libaioゲスト側 I/O engine は libaio のまま固定する
–direct=1ゲスト OS のページキャッシュを避ける
–runtime=6060 秒間の time based テストにする

テスト結果

この環境では、io_uring を有効化した場合に IOPS と帯域が約 15% 改善しました。平均レイテンシだけでなく、p50、p70、p90、p95 も低下しています。

指標io_uring 無効io_uring 有効差分
IOPS8,2139,425+14.7%
帯域32.1 MiB/s36.8 MiB/s+14.6%
平均 latency3.89 ms3.39 ms-0.50 ms
p503,490 us2,933 us-557 us
p706,194 us5,538 us-656 us
p908,455 us7,767 us-688 us
p959,503 us8,717 us-786 us
sys CPU18.29%28.70%+10.41%
disk util99.88%99.90%ほぼ同等

結果の読み方

IOPS と帯域は改善した

今回の条件では、IOPS と帯域はどちらも約 15% 改善しました。4KB randread / iodepth 32 という細かい I/O が多い条件では、QEMU の I/O backend を io_uring にすることでホスト側 I/O 経路の効率が改善したと見られます。

p50 から p95 の latency が下がった

平均値だけでなく、p50 から p95 の latency が下がっている点は重要です。これはピーク性能だけではなく、通常時からやや遅い側までの応答性が改善していることを示します。

sys CPU は増えている

sys CPU は 18.29% から 28.70% に増えています。これは必ずしも悪い結果ではありません。I/O をより積極的に処理した結果として kernel 側の CPU 使用が増え、その代わりに I/O 待ちや latency が減っている可能性があります。

ただし、CPU に余裕がないホストでは、この sys CPU 増加が別の制約になる場合があります。io_uring を標準化する前に、ホスト CPU の余裕も確認するべきです。

io_uring が効きやすい条件

この検証から、io_uring は特に小さい I/O が高頻度に発生する VM で効果を期待しやすいと考えられます。

  • Kubernetes ノード
  • ログ処理や CI/CD エージェント
  • 小さなファイルを頻繁に扱う VM
  • 軽量 DB やキャッシュ系を含む混在環境
  • qcow2 など QEMU 側 I/O 経路の影響を受けやすい構成

一方で、ストレージ backend が別の場所で詰まっている場合や、大きな sequential I/O が中心の場合は、同じ傾向になるとは限りません。

標準設定にする前に確認すること

今回の結果だけを見ると io_uring は有効な選択肢です。ただし、すべての KVM 環境で無条件に標準化してよいとまでは言い切れません。

  • QEMU と libvirt が io_uring を安定して扱えるバージョンか
  • kernel バージョンとストレージ backend の組み合わせに問題がないか
  • raw / qcow2 / block device / RBD / ZFS など backend ごとの差を確認したか
  • IOPS だけでなく p95 / p99 latency を確認したか
  • sys CPU 増加をホストが許容できるか
  • 本番 VM と同じ I/O パターンで測定したか

VM パフォーマンス Day4 との関係

VM パフォーマンス Day4 では、ストレージ I/O を virtio、QEMU、ホスト OS、物理ストレージの多段経路として整理しました。この記事の io_uring 検証は、その中でも QEMU からホスト I/O backend へ出ていく部分を変更した検証です。

つまり、io_uring は VM 内のアプリケーションを変える技術ではなく、ホスト側 QEMU の I/O 経路を効率化する選択肢として見ると分かりやすくなります。

まとめ

この検証環境では、QEMU の disk driver に io_uring を指定することで、4KB randread の IOPS と帯域が約 15% 改善し、p50 から p95 の latency も低下しました。

一方で、sys CPU は増加しており、効果は QEMU、kernel、ストレージ backend、ディスク形式、I/O パターンに依存します。したがって、io_uring は有力な選択肢ですが、本番適用前には自分の環境で測定するべきです。

KVM のストレージ I/O を考えるときは、ゲスト側の I/O engine だけでなく、QEMU がホスト側でどの I/O backend を使うかも性能設計の対象になります。

参考
書籍
参考書籍

作って理解する仮想化技術 ── ハイパーバイザを実装しながら仕組みを学ぶ

ハイパーバイザ、CPU 仮想化支援、メモリ仮想化、割り込み、仮想デバイスなど、VM の性能設計を低レイヤから理解したい場合の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

関連記事

KVM の io_uring はどれだけ効くのか – QEMU ストレージ I/O の検証

コメントを残す

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

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

トップへ戻る