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 | 変更なし |
| ホスト側 QEMU | disk driver | io='io_uring' の有無 |
| 評価対象 | ゲスト内 fio の結果 | IOPS / BW / latency |
QEMU で io_uring を有効化する
まず、ホスト側 kernel で io_uring が有効になっているかを確認します。
grep IO_URING /boot/config-$(uname -r)次のように有効であれば、kernel 機能としては利用可能です。
CONFIG_IO_URING=ylibvirt の 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=randread | 4KB ランダムリードを実行する |
| –bs=4k | 小さい I/O を高頻度に発行する |
| –iodepth=32 | 同時に 32 個の I/O を発行する |
| –ioengine=libaio | ゲスト側 I/O engine は libaio のまま固定する |
| –direct=1 | ゲスト OS のページキャッシュを避ける |
| –runtime=60 | 60 秒間の time based テストにする |
テスト結果
この環境では、io_uring を有効化した場合に IOPS と帯域が約 15% 改善しました。平均レイテンシだけでなく、p50、p70、p90、p95 も低下しています。
| 指標 | io_uring 無効 | io_uring 有効 | 差分 |
|---|---|---|---|
| IOPS | 8,213 | 9,425 | +14.7% |
| 帯域 | 32.1 MiB/s | 36.8 MiB/s | +14.6% |
| 平均 latency | 3.89 ms | 3.39 ms | -0.50 ms |
| p50 | 3,490 us | 2,933 us | -557 us |
| p70 | 6,194 us | 5,538 us | -656 us |
| p90 | 8,455 us | 7,767 us | -688 us |
| p95 | 9,503 us | 8,717 us | -786 us |
| sys CPU | 18.29% | 28.70% | +10.41% |
| disk util | 99.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 アソシエイトリンクです。
関連記事
- VM パフォーマンス Day4 – ストレージ I/O 最適化と virtio / raw / qcow2 / io_uring の考え方
- VM パフォーマンス最適化 – NUMA / CPU / I/O / ネットワークの設計ハブ
- VM パフォーマンス Day8 – DPDK による高速 dataplane と NFV の基本
- Ubuntu 22.04 OVS-DPDK 構築失敗
- VyOS VPP 導入検討 – 実運用ルーターに VPP をそのまま適用する難しさ





