VPSベンチマークの正しい測り方と結果の読み方
まずyabs.shを実行し、fio、sysbench、iperf3で結果を検証します。CPU、メモリ、ディスク、回線の数値が何を意味するか、なぜ1回の測定では判断できないかを解説します。
VPSのベンチマークが意味すること
VPSのベンチマークでは、4つの項目を測定します。1つのCPUコアの処理速度、マシンのメモリ帯域幅、ストレージが1秒あたりに処理できる小さなランダムディスク操作の数、そしてネットワークリンクが提供するスループットです。yabs.shを1回実行すれば、約10分ですべてを測定できます。結果の読み取りのほうが難しい作業です。VPS(仮想プライベートサーバー)は他のテナントと物理ハードウェアを共有するためです。そのため、同じマシンでも03:00には1つの値を、20:00には大きく異なる値を報告することがあります。
ここでは、まずyabs.shを実行して概要を確認し、その後で内部で使用されるツールを手動で実行します。自分で実行すれば、1つのフラグだけを変更し、値がどう変化するかを確認できます。これにより、その値が実際に何を測定していたのかを理解できます。これはマシンのセットアップ後に実行してください。セットアップ前ではありません。まず新しいVPSで最初の10分間に行うことの手順を完了してください。初回の更新をまだ適用しているマシンでは、ハードウェアとは無関係の理由でベンチマーク結果が悪くなるためです。
測定する前にマシンを確認する
不正確なベンチマークの半分は、作成者がマシンを理解していないことが原因です。
nproc
lscpu | grep -E 'Model name|Hypervisor|Thread'
free -h
df -hT /
uname -r
systemd-detect-virtHypervisor vendor: KVM は完全仮想化を意味するため、独自のカーネルを実行します。systemd-detect-virt の出力で lxc または openvz と表示される場合は、コンテナ仮想化です。ホストのカーネルを共有し、CPU とメモリの上限は仮想ハードウェアではなく cgroup(control group)の設定になります。cgroup v2 システムでは、CPU 制限を直接確認できます。
cat /sys/fs/cgroup/cpu.maxmax 100000 はクォータがないことを意味します。200000 100000 は、100000 マイクロ秒の各期間で 200000 マイクロ秒分の CPU を使用できることを意味します。これは 2 コア分のクォータです。4 vCPU として宣伝されているプランでも、クォータが 2 コア分しかなければ、4 コアとしてのスコアにはなりません。ベンチマークツールが、その理由を示す行を出力することもありません。
df -hT / が重要なのは、別の理由です。Type 列を確認するためです。overlay と表示される場合はコンテナ内にいるため、以下のディスクテストを変更する必要があります。ここで記録しておいてください。
常にsteal timeを監視する
Steal timeは、仮想CPUが実行可能な状態だったにもかかわらず、ハイパーバイザーが物理コアを別の処理に割り当てた時間の割合です。これは、結果の原因がハードウェアではなく、同じホスト上の他の利用者にあることを示す、最も有用な単一の指標です。
vmstat 1 10右側のst列を確認します。0または1で安定していれば正常です。5を超える値が継続する場合、その時点でホストのリソースが過剰に割り当てられています。そのため、その時間帯に記録したCPU値は、マシンに問題がなくても低くなります。topには、CPU行の%stと同じ値が表示されます。ベンチマーク中は、別のSSHセッションでvmstat 1を実行し続け、各結果の横にstealの値を記録します。
yabs.shから始める
yabs.sh(Yet Another Bench Script)は、静的なfio、iperf3、Geekbenchのバイナリをダウンロードして実行し、結果を1つにまとめて表示するシェルスクリプトです。VPSのベンチマークに関する議論で共通して使われるため、yabsの出力は他のユーザーと結果を比較する最も簡単な方法です。
プロジェクトが案内している1行形式は次のとおりです。
curl -sL yabs.sh | bashこれは、URLが現在提供している内容をそのままシェルに渡して実行します。ダウンロードして内容を確認してから実行してください。
curl -sLo yabs.sh https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/yabs.sh
less yabs.sh
bash yabs.shパイプで実行する場合は-s --の後に、ローカルコピーを実行する場合はファイル名の直後にフラグを指定します。主なフラグは、-fがディスクテストを省略し、-iがネットワークテストを省略し、-gがGeekbenchを省略し、-rがiperf3の接続先を2か所に減らし、-jが結果をJSONで表示し、-w results.jsonがそのJSONをファイルに書き込みます。
bash yabs.sh -r -w yabs-run1.json初回実行前に、2点確認してください。Geekbenchは結果をアップロードし、公開されたbrowser.geekbench.comのURLを表示します。そのため、そのURLを知っている人は誰でもCPUモデルとスコアを確認できます。-gを指定すると、このテストを完全に省略できます。次に、iperf3のステージでは、複数の地域にあるサーバーへ実際のネットワークトラフィックを送信します。これは月間の帯域幅上限に加算されます。1 Gbit/sの回線では、ネットワークステージ全体で数十GBのトラフィックが発生する場合があります。上限が小さい場合は-rを使用し、従量制の回線では-iを使用してください。
yabs の出力の各項目の意味
ディスクセクションでは、4k、64k、512k、1m の4つのブロックサイズで、読み取りと書き込みを50/50で混在させて fio を実行します。それぞれについて、IOPS(1秒あたりの入出力処理数)と帯域幅を報告します。データベース、メールサーバー、または小さな書き込みを大量に処理するシステムでは、4k の行を確認します。ほとんどのサーバー IO は小さく、分散しているためです。バックアップや動画では、連続した大量のバイトを転送するため、1m の行を確認します。
ネットワークセクションでは、複数のリージョンにある公開サーバーに対して、両方向で並列ストリームを使用して iperf3 を実行します。ここで低い数値が出ても、すぐに結論を出さず、確認が必要な結果として扱います。公開 iperf3 サーバーは共有されており、飽和していることも多いためです。結果が悪い原因は、接続先にある可能性があります。
Geekbench セクションでは、シングルコアスコアとマルチコアスコアを示します。シングルコアスコアは、1つのリクエスト、1回のコンパイル、または1つのクエリが完了する速度の目安になります。マルチコアスコアは主に、実際に割り当てられたコア数を示します。
Disk: fioを自分で実行する
fio(flexible IO tester)は、yabsのディスクセクションで使用される基盤ツールです。直接実行すると、各フラグの意味が明確になります。
sudo apt update && sudo apt install -y fio sysbench iperf3実際に使用するファイルシステム上で、キュー深度32の4kランダム読み取りテストを実行します。
fio --name=randread4k --filename=./fio-testfile --size=2G --bs=4k \
--rw=randread --ioengine=libaio --iodepth=32 --direct=1 \
--runtime=60 --time_based --group_reporting出力から読み取るサマリー行は次のようになります。
read: IOPS=184k, BW=719MiB/s (754MB/s)(42.1GiB/60001msec)その下で、fioはclat percentilesブロックを出力します。引用する価値があるのは99.00パーセンタイルです。100件中で最も遅い1件のリクエストが待機した時間を示すためです。平均レイテンシでは、ユーザーが実際に気付く停止時間が隠れます。
--direct=1はO_DIRECTでファイルを開くため、読み取りはkernel page cacheを経由しません。これを指定しない場合、RAMが8Gあるマシンで2Gファイルを2回目に読み取ると、メモリから処理され、fioはIOPSを数百万と報告します。その数値は実在しますが、メモリの性能を示しています。--ioengine=libaioは非同期リクエストを送信します。これにより、--iodepth=32は32件をin flightに維持できます。psyncのような同期engineでは、iodepthを1より大きくしても何も起きません。そのため、1件ずつリクエストを測定することになります。--time_based --runtime=60は処理量を固定する代わりに、60秒間実行します。これにより、高速なディスクと低速なディスクで同じwall clock時間になり、比較が公平になります。--size=2Gはテストファイルのサイズを設定します。パス上にあるすべてのcacheより大きくし、先に空き容量があることを確認してください。
ランダム書き込みでは、同じコマンドに--rw=randwriteを指定します。別々に実行し、その後でファイルを削除してください。
fio --name=randwrite4k --filename=./fio-testfile --size=2G --bs=4k \
--rw=randwrite --ioengine=libaio --iodepth=32 --direct=1 \
--runtime=60 --time_based --group_reporting
rm -f ./fio-testfile実際のトラフィックに近い混合処理には、--rw=randrw --rwmixread=70を使用します。使用しているストレージの種類による結果の差は、どのフラグによる差よりも大きくなります。この違いについては、VPSのNVMeストレージとSATA SSDストレージの違いで説明しています。
fio が Unknown error -1 で停止する場合
ダイレクト I/O は、すべてのファイルシステムで利用できるわけではありません。overlay、Docker がコンテナにデフォルトで提供するファイルシステム、および一部のネットワークファイルシステムは O_DIRECT をサポートしていません。そのため、libaio はカーネルが完了できないリクエストを送信し、fio は処理を中止します。
fio: io_u error on file ./fio-testfile: Unknown error -1: read offset=0, buflen=4096
fio: pid=1234, err=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1まず df -hT . を実行します。Type 列が overlay の場合は、--filename を bind mount したボリュームなど、実際のストレージ上のパスに指定します。または、コンテナ内ではなくホスト上で fio を実行します。実際のストレージを使用できない場合は、バッファリングされた同期実行でも、コマンド自体が正しいことを確認できます。
fio --name=randread4k-buffered --filename=./fio-testfile --size=256M --bs=4k \
--rw=randread --ioengine=psync --direct=0 --numjobs=1 \
--runtime=15 --time_based --group_reporting
rm -f ./fio-testfileこの実行結果が示す内容を正しく理解してください。最初の実行後は、256M のファイルがページキャッシュに残るため、IOPS の値は RAM の性能を示します。fio がインストールされ、フラグが正しく解釈されることの確認に使用してください。ディスクの結果として引用しないでください。
ddがディスクベンチマークではない理由
ddは多くのVPSのスレッドで取り上げられますが、答えられるのは限定的な質問です。
dd if=/dev/zero of=./ddtest bs=1M count=1024 oflag=direct conv=fdatasync
rm -f ./ddtestこれは、1スレッドで1つのリクエストを処理中にした場合の、シーケンシャル書き込みスループットを測定します。簡単な健全性チェックとしては適切です。ランダムIOについては何も分かりません。また、32個のリクエストが同時に到着した場合の動作も分かりません。oflag=directを省略すると、主にkernelがメモリへの書き込みをどれだけ速く受け付けるかを測定することになります。そのため、フォーラムの投稿で引用されるddの数値は、しばしば現実離れしたものになります。
CPU: sysbench cpu
sysbench cpu --cpu-max-prime=20000 --threads=1 run
sysbench cpu --cpu-max-prime=20000 --threads=$(nproc) run確認する数値は events per second です。まずシングルスレッドで実行します。この数値は、1つの PHP リクエストが完了する速さや、1つのコンパイルジョブが完了する速さを左右します。同じ価格帯のホスト間で最も差が出やすい数値でもあります。次に、すべてのスレッドを使用して実行します。これにより、vCPU が独立したコアなのか、1つのコアを分割したものなのかを確認できます。
このテストで測定できる範囲を明確にしておきます。sysbench cpu は、64 bit 整数演算を使って素数を繰り返し検索します。メモリ帯域幅、ベクトル演算ユニット、キャッシュは、実際のワークロードに近い形では負荷をかけません。そのため、2台のホストを比較する用途には適していますが、アプリケーションの実行速度を予測する用途には適していません。
Ubuntu 24.04 には sysbench 1.0.20 が含まれており、このバージョンではテスト名を先に指定します。古い記事にある --test=cpu を使ったコマンドをコピーすると、WARNING: the --test option is deprecated になります。sysbench 0.4 と sysbench 1.0 のスコアはまったく比較できません。そのため、バージョンが明記されていない公開スコアを基準にしてはいけません。
メモリ: sysbench memory
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=write --threads=1 run
sysbench memory --memory-block-size=1M --memory-total-size=20G --memory-oper=read --threads=1 run結果は MiB/sec 単位です。すべてのマシンで、読み取りは書き込みより高速になります。比較するすべてのホストで、--memory-block-size は 1M に設定し、同じ値にしてください。1K では、操作ごとのオーバーヘッドが1000倍多く発生するため、値が大幅に低下します。その結果、メモリ帯域幅ではなく、ループのコストを測定することになります。これは、公開されているメモリスコアで最も頻繁に一致していないフラグです。
ネットワーク: iperf3
スループットを正確にテストするには、自分が管理する別のマシンを相手にします。両端で何が実行されているかを把握できるためです。
相手側で次を実行します。
iperf3 -sTCP 5201で待ち受けます。テスト元のアドレスに対してのみポートを開き、終了したら閉じてください。VPSでの基本的なufwファイアウォールルールで構文を説明しています。
テスト対象のVPSから次を実行します。
iperf3 -c 203.0.113.10 -t 30
iperf3 -c 203.0.113.10 -t 30 -R
iperf3 -c 203.0.113.10 -t 30 -P 8最初のコマンドは、テスト対象マシンからのアップロードを測定します。-Rは方向を反転し、ダウンロードを測定します。-P 8は8本の並列ストリームを開きます。
単一ストリームと並列版の両方を実行してください。両者は異なる点を確認するためです。1本のTCP接続で保持できる未確認応答データ量は、ウィンドウサイズが許容する範囲に限られます。そのため上限は、おおよそウィンドウサイズを往復遅延時間で割った値です。遅延が80 msでウィンドウが4 MBの場合、基礎となるリンクがどれほど高速でも、上限は約400 Mbit/sです。単一ストリームの値から、1回のダウンロードで得られる速度が分かります。並列実行の値から、リンクの容量が分かります。
実行中は、帯域幅の使用許容量を確認してください。1 Gbit/sで30秒間実行すると約3.75 GB転送されます。各方向で複数回実行することになります。
参考値と測定結果の読み方
The data behind this chart
[
{
"device": "Local NVMe",
"iops_4k_read": "180,000"
},
{
"device": "Local SATA SSD",
"iops_4k_read": "90,000"
},
{
"device": "Network block",
"iops_4k_read": "12,000"
},
{
"device": "Spinning disk",
"iops_4k_read": "180"
}
]公開されている結果では、ローカルの NVMe ボリュームは通常、180,000 4k ランダム読み取り IOPS 前後になります。ローカルの SATA SSD は約 90,000 です。ネットワーク接続型のブロックストレージは、すべてのリクエストがディスクに到達する前にネットワークを経由するため、12,000 付近になります。回転ディスクは、ランダムリクエストごとに物理ヘッドを移動するため、およそ 180 です。
これらは各ストレージクラスで一般的な公開値であり、1台のホストで測定した値ではありません。用途は1つだけです。自身の結果が同じ桁に収まっているかを確認するために使います。NVMe として販売されているプランで 4k IOPS が数千台にとどまる場合は、まず --direct=1 が有効だったことを確認してください。有効だった場合は、ストレージが製品ページの説明と異なるか、非常に負荷の高い隣接ユーザーと共有している可能性があります。
1回の実行結果はベンチマークではありません
1回の結果は、共有マシン上の1分間の状態を示すスナップショットにすぎません。1つのサンプルとして扱ってください。
- 各テストを少なくとも5回実行し、異なる時間帯と少なくとも2日間に分散させてください。中央値とばらつきを記録してください。ばらつきを示さずに公開された結果は、マーケティング用の数値です。
- 各実行の横に steal time を記録してください。
stが高かった実行は除外するか、少なくともその事実を注記してください。 - ディスクテストは2種類の実行時間で行ってください。多くのプランには、時間経過で補充されるバースト IOPS の許容量があります。そのため、60秒間の fio 実行ではバースト性能が測定され、
--runtime=600では下限性能が測定されます。悪い日に得られるのは下限性能です。 - ほかの処理が実行されていないことを確認してください。CPUテストの途中で
unattended-upgradesが apt トランザクションを開始すると、実際のスコアが下がります。また、各実行前のps -e -o comm= | grep -E 'apt|dpkg'には1秒かかります。 - 一度に1つの変数だけを変更してください。ツールのバージョン、ブロックサイズ、スレッド数が異なると、見た目がどれだけ似ていても比較できない数値になります。
2つのプロバイダーを比較する場合は、同じ日の同じ時間帯に実行してください。そうしないと、測定しているのは時間帯です。
自分のワークロードを最後にベンチマークする
合成ベンチマークツールはマシンを順位付けします。マシンが十分かどうかを判断できるのは、自分のワークロードだけです。実際に行う処理の時間を測定してください。
time tar -czf /tmp/bench.tgz /usr/share
rm -f /tmp/bench.tgzこれは数百MBを圧縮するため、CPUとディスクを同時に使用します。そのため、どちらかが変わると結果も変わります。Removing leading / from member names の警告は正常です。さらに良い方法は、自分のビルド、自分の最も遅いクエリ、または自分のページレンダリングの時間を測定することです。あるホストで4分、別のホストで7分かかるビルドなら、Geekbenchの評価に関係なく結論は明らかです。これは、より高性能なマシンに費用をかけても効果がなくなる時点を判断するための測定でもあります。VPSの実際の月額を確認したり、ワークロードを専用サーバーへ移行したりする前に知っておく価値があります。
FAQ
実行するたびにベンチマーク結果が異なるのはなぜですか?
VPSは他のテナントと物理CPU、ストレージ、ネットワークを共有するため、その時点で他のテナントが何をしているかによって結果が変わります。テスト中にvmstat 1を実行し、st列を確認してください。steal timeが5を超えた状態で継続している場合、ホストがビジーであり、CPUスコアが低い原因はマシンの外部にあります。重要なのはチューニングではなく、測定方法です。異なる時間帯に各テストを5回以上実行し、ばらつきとともに中央値を報告してください。
fioが数百万IOPSを報告するのはなぜですか?
ほとんどの場合、--direct=1が指定されていないことが原因です。指定しない場合、fioはkernel page cacheを経由して読み取ります。そのため、最初のパスの後は2GのテストファイルがRAMから提供され、メモリ帯域幅を測定することになります。--direct=1を追加し、テストファイルを経路上のどのcacheよりも大きくしてください。--direct=1がerr=-1/file:ioengines.c:321, func=get_events, error=Unknown error -1で失敗する場合は、df -hT .を実行してください。overlayのTypeはO_DIRECTをサポートしていないため、テスト対象を実際のストレージに変更します。
yabs.shだけで十分ですか?
最初の確認には十分です。4種類のブロックサイズでfioを実行し、両方向でiperf3を実行し、他の人も読める1つのサマリーを出力します。ただし、数値の理由を確認したい場合は不十分です。テストごとにflagsを変更できないためです。yabsの結果が不自然に見えたら、fioまたはsysbenchで直接再現し、一度に1つのflagだけを変更してください。
アプリケーションの体感性能を予測できる単一の数値は何ですか?
ほとんどのWebおよびデータベースのワークロードでは、順にsingle core CPU speedと4k random read latencyです。一般的なリクエストは小さいため、スループットの数値は目立つ一方で、結果を左右することはほとんどありません。平均値ではなく、fioのclat percentilesブロックから99パーセンタイルを示してください。100回に1回の遅いリクエストをユーザーが認識するためです。
ベンチマークの前に何かをインストールする必要がありますか?
fio、sysbench、iperf3はすべてUbuntuおよびDebianのアーカイブにあります。sudo apt install -y fio sysbench iperf3です。yabs.shにはcurlだけが必要です。不足しているものは静的バイナリをダウンロードするためです。終了したら、すべてのテストファイルを削除してください。20Gのディスクに2Gのfioファイルを残すと、数週間後にディスクフルのアラートが発生する原因になります。