Persistent Diskのパフォーマンスについて
こんにちは。Google Cloud Supportの笠井です。
Google Cloud Japan Advent Calendar 2024 の25日目、最後の記事になります。
最後の記事なのに少し地味ではありますが、本記事ではPersistent Disk(以下PD)のパフォーマンスについて、少し解説してみたいと思います。
Google Compute Engineでは、PDのパフォーマンスはIOPSとスループットという指標によって測られます。
本記事ではこれらのパフォーマンスについて、改めておさらいしてみたいと思います。
PDの種類
PDの種類は、こちらに記載されているように4種類あります。
基本的には上から下に進むに向かってパフォーマンスが良くなります。
- 標準永続ディスク
- バランス永続ディスク
- パフォーマンス永続ディスク
- エクストリーム永続ディスク
この記事では主に、多く使われているバランス永続ディスク、パフォーマンス永続ディスクに関して記述していきます。
パフォーマンスの計算方法
エクストリームPDを除く各PDには、ベースラインパフォーマンスと共に、GiBあたりのパフォーマンスが提供されており、これをベースに期待パフォーマンスの計算を行います。
期待されるパフォーマンスの上限として、マシンとしての上限と、ディスクあたりの上限があるため、これも考慮します。
単一PDに対する基本的な期待パフォーマンスの計算式としては、IOPSもスループットも以下のようになります。
計算例
例えば、以下のようなケースを考えます。
- E2 VM
- 4 vCPU
- 100GiB Zonal pd-ssd
このケースでは、IOPSは
となり、スループットは
となります。
実測
こちらにあるfioコマンドを利用し、上記のpd-ssdに対してパフォーマンステストをかけてみます。
IOPS測定
ext4ファイルシステムを構成して/mount/disks/sdbにマウントし、コマンドは以下を利用します。
今回はIOPSの上限を見るため、ブロックサイズを1Kに指定します。
コマンド
sudo fio --name=read_iops --directory=/mount/disks/sdb \
--numjobs=16 --size=1G --time_based --runtime=5m --ramp_time=2s \
--ioengine=libaio --direct=1 --verify=0 --bs=1K --iodepth=64 \
--rw=randread --group_reporting=1 --iodepth_batch_submit=64 \
--iodepth_batch_complete_max=64
結果
read: IOPS=8997, BW=9000KiB/s (9217kB/s)(2638MiB/300120msec)
IOPS = 8997と、ほぼ上限に近い値が出ました。
メトリクスで見ても、9000 IOPSになっていることが分かります。
スループット測定
今度はブロックサイズを256Kに設定し、スループット上限を確認します。
コマンド
sudo fio --name=read_throughput --directory=/mount/disks/sdb \
--numjobs=16 --size=1G --time_based --runtime=5m --ramp_time=2s \
--ioengine=libaio --direct=1 --verify=0 --bs=256K --iodepth=64 \
--rw=randread --group_reporting=1 --iodepth_batch_submit=64 \
--iodepth_batch_complete_max=64
結果
read: IOPS=1916, BW=240MiB/s (252MB/s)(70.4GiB/300532msec)
結果は240MiB/sと、こちらも上限の値が出ています。
メトリクスで確認しても以下の通りです。
シーケンシャルな操作の場合
今まで、--rw=randreadと、ランダムアクセスによる測定を実施してきました。
次は--rw=readと、シーケンシャルなアクセスで試してみます。
IOPS測定で試したブロックサイズ 1Kに対して試してみます。
コマンド
sudo fio --name=read_iops --directory=/mount/disks/sdb \
--numjobs=16 --size=1G --time_based --runtime=5m --ramp_time=2s \
--ioengine=libaio --direct=1 --verify=0 --bs=1K --iodepth=64 \
--rw=read --group_reporting=1 --iodepth_batch_submit=64 \
--iodepth_batch_complete_max=64
結果
read: IOPS=63.6k, BW=62.1MiB/s (65.1MB/s)(18.2GiB/300015msec)
IOPS = 63600、スループット = 62.1MiBという、IOPSの上限を大幅に超えた結果が出ました。
これはどういうことでしょうか?
Disk Operationsは、前回のテストと同じ9kを示しており、この結果を説明できません。
ここで登場するのがmerged_operation_countです。
これは、隣あったブロックに対する複数のI/O操作をカーネルがマージして1つの操作にする、I/Oのマージ操作を行った回数をカウントしています。
すごく簡単に言えば、隣あったブロックに1Kずつ、2つのI/O操作があった場合、この2つをマージして合計2K、1回のI/O操作にしてしまう、ということです。
グラフを見ると、このマージ操作の数が急増していることが見てとれます。
fioからは複数のI/O操作であったとしても、PDから見た時には1つのI/O操作として見えているため、fioで測定したIOPSとPDで測定したIOPSに差が出てくるというわけですね。
例外ケース
ここまで単一のPersistent Diskを対象としてお話しして来ましたが、上で紹介した期待パフォーマンスの計算式通りに必ずしもいかないケースが存在します。
例えば、同じタイプのディスクを複数アタッチしている場合では、サイズによるパフォーマンスは合計したものが適用されますが、ベースラインパフォーマンスについてはディスク1つ分しか与えられません。
つまり、例えば50GiBのZonal pd-ssdを2つアタッチした場合、トータルの期待パフォーマンスは
ではなく、100 GiBのpd-ssdを一つアタッチした場合と同じ、
と、なります。
pd-ssdとpd-standardのような、タイプの異なるPDをアタッチした場合はこうはならず、それぞれにベースラインパフォーマンスが適用されます。
PD観点の他にも、ワークロードの問題や、オペレーティングシステムやファイルシステムの問題など、考慮すべき点はありますので、PDのパフォーマンスに困った際はこれらを参照してみてください。
終わりに
PDのパフォーマンスは基本的な部分ではあるものの、一方で一見して分かりにくい点があるのも事実です。
本記事が理解の一助となりましたら幸いです。
Discussion