当てずっぽうな運用は卒業:fioによるLinuxディスク性能のベンチマーク手法

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

午前2時のパフォーマンス危機

Grafanaのダッシュボードが真っ赤に染まっていました。午前2時、数ヶ月間安定していたトラフィックの多いPostgreSQLデータベースが、突然悲鳴を上げ始めたのです。クエリ時間は3倍になり、I/Oウェイトは40%に達していました。それにもかかわらず、クラウドプロバイダーのステータスページは「Premium NVMe Storage」は正常であると、すべて緑色で表示されていました。しかし、ターミナルが告げる事実は全く別のものでした。

数十台のLinuxインスタンスを管理してきた経験から、私は一つの教訓を得ました。それは「スペックシートを絶対に信じるな」ということです。「高性能」と謳われているドライブでも、4Kビデオのシーケンシャルアクセスでは素晴らしい速度を出すかもしれませんが、データベースのような大量の小さなランダム書き込みには耐えられないことがあります。真実を知るために、私はfio (Flexible I/O Tester) を使用しています。これは、ストレージハードウェアに現実世界の負荷をシミュレートするための業界標準ツールです。

なぜddはベンチマークとして不適切なのか

多くのシステム管理者は、ディスク速度をテストするためにddを使おうとします。dd if=/dev/zero of=testfile bs=1G count=1 oflag=directといったコマンドを見たことがあるでしょう。ddは5秒程度の簡易的な動作確認には適していますが、本番環境の計画には役に立ちません。シーケンシャル書き込みしかテストできず、現代のストレージコントローラーの複雑さや、同時アクセスの混乱を無視しているからです。

本番環境では、ディスクは一度に一つのことだけを行うわけではありません。何百もの同時リクエストを処理します。あるプロセスが設定ファイルを読み込み、別のプロセスが50MBのログを書き込み、さらに別のプロセスがデータベースのインデックスを更新します。サーバーがその負荷に耐えられるかどうかを理解するには、次の3つの指標を追跡する必要があります。

  • IOPS (Input/Output Operations Per Second): ディスクが1秒間に完了する小さなリクエスト(通常は4KB)の数。これはデータベースのパフォーマンスの生命線です。
  • スループット (帯域幅): 1秒間に転送されるデータの量 (MB/s)。バックアップや大きなファイルの転送において重要です。
  • レイテンシ: 単一のI/Oリクエストが完了するまでにかかる時間。レイテンシが低いと、サーバーのレスポンスが軽快に感じられます。

fioのインストール

fioは軽量で、ほぼすべての公式リポジトリで利用可能です。システムを肥大化させたり、依存関係を壊したりすることはありません。

UbuntuまたはDebianユーザーの場合:

sudo apt update
sudo apt install fio -y

RHEL、CentOS、またはAlmaLinuxの場合:

sudo yum install epel-release -y
sudo yum install fio -y

データベーステスト:ランダム読み取り/書き込み

ランダムI/Oは、Webサーバーで最も頻繁に発生するボトルネックです。ディスクが4KBのランダム書き込みを処理できない場合、アプリケーションはいずれハングアップします。このコマンドは、非シーケンシャルなデータに対してディスクを酷使させることで、重いデータベースのワークロードをシミュレートします。

fio --name=random-rw --ioengine=libaio --rw=randrw --bs=4k --numjobs=1 --size=2G --runtime=60 --time_based --do_verify=0 --direct=1 --group_reporting --iodepth=64 --filename=fiotest.tmp

主要なフラグの解説:

  • --ioengine=libaio: Linuxネイティブの非同期I/Oを使用します。これはMySQLやNGINXなどの現代的なアプリケーションがカーネルとやり取りする方法を模倣します。
  • --rw=randrw: ランダムな読み取りと書き込みを同時に実行します。
  • --bs=4k: ブロックサイズを4KBに設定します。これはほとんどのファイルシステムの標準的なページサイズです。
  • --direct=1: OSのバッファキャッシュをバイパスします。これにより、サーバーのRAMではなく、実際のハードウェアをテストしていることが保証されます。
  • --iodepth=64: 一度に64個のリクエストを処理待ち状態に保ち、ドライブのキュー管理能力をテストします。
  • --filename=fiotest.tmp: テストに使用するファイル。注意: ドライブをフォーマットするつもりがない限り、これを /dev/nvme0n1 のような生デバイスに直接指定しないでください。

バックアップテスト:シーケンシャルスループット

100GB of ログファイルを移動したり、システムバックアップを実行したりする速度を知る必要がある場合は、より大きな1MBのブロックサイズを使用したシーケンシャルテストが必要です。

fio --name=sequential-write --ioengine=libaio --rw=write --bs=1m --numjobs=1 --size=2G --runtime=60 --time_based --do_verify=0 --direct=1 --group_reporting --iodepth=32 --filename=fiotest.tmp

このシナリオでは、BW (Bandwidth) の結果に注目してください。現代的なGen4 NVMeドライブであれば、3,000 MB/sを容易に超えるはずです。標準的なSATA SSDは通常540 MB/s程度で頭打ちになります。もし100 MB/sを下回る数値が出た場合は、クラウドのボリューム制限(スロットリング)にかかっているか、古い機械式のハードドライブを扱っている可能性があります。

混乱せずに結果を読み解く

fioは大量のテキストを生成しますが、注目すべきは数行だけです。中堅クラスのSSDの典型的な結果は以下のようになります。

read: IOPS=15.4k, BW=60.2MiB/s (63.1MB/s)(3612MiB/60001msec)
  lat (usec) : min=412, max=15432, avg=1024.05, stdev=342.12

15.4k IOPSは良い数値でしょうか? 標準的なクラウドVPS(デフォルト設定のAWS gp3ボリュームなど)では、3,000 IOPSがベースラインです。ハイエンドのNVMeドライブは500,000 IOPSを超えることもあります。もし「エンタープライズ」ストレージが負荷時に1,000 IOPSを下回っているなら、何かがおかしいと言えます。

レイテンシを確認する: avg(平均)を見てください。単位はマイクロ秒 (usec) またはミリ秒 (msec) です。本番環境のデータベースでは、平均レイテンシを1msまたは2ms以下に保ちたいところです。もし max(最大)レイテンシが頻繁に100msを超えるようであれば、ユーザーは目に見えるラグを感じることになります。

結論

午前2時に苦闘していたサーバーで fio を実行した結果、事実は明白でした。IOPSは500で頭打ちになっていました。これは2012年頃のノートPC用ドライブと同程度の速度です。私は fio のログをプロバイダーのサポートチームに送りました。確たるデータを突きつけられた彼らは、ホストノードのRAIDコントローラーに障害が発生していたことを認めました。彼らはすぐに私のインスタンスを新しいハイパーバイザーに移行しました。10分後、I/Oウェイトは0.5%に下がり、データベースはフルスピードに戻りました。

ハードウェアの状態を把握するのに、危機が発生するまで待つ必要はありません。デプロイ前にこれらのベンチマークを実行しましょう。マーケティングが嘘をついても、データは嘘をつきません。

Share: