fioコマンドでLinuxサーバーのディスクI/Oをベンチマークする方法|ランダム読み書き・シーケンシャル・混在の実測手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxトラブルシューティング > fioコマンドでLinuxサーバーのディスクI/Oをベンチマークする方法|ランダム読み書き・シーケンシャル・混在の実測手順
「サーバーのディスクが遅いかもしれないが、どうやって数値で確認すればいい?」
「iostatで%utilが高いのは分かったが、これはもう限界なのか、まだ余裕があるのか判断できない……」

そのディスクの「本来の最大性能」を知らないまま障害対応しても、判断の根拠が曖昧になります。ベンチマーク値がなければ「%util 80%が普通なのか危険水域なのか」を判定できないのです。

この記事では、Linuxサーバーのディスクパフォーマンスを定量評価するためのベンチマークツール「fio」の使い方を解説します。シーケンシャル・ランダム・混在負荷の計測手順から、bw・IOPS・clatの出力の読み方、iostatと組み合わせた高負荷時の診断まで、RHEL 9 / Rocky Linux 9 / Ubuntu 24.04 LTSで動作確認した実機例でカバーします。

この記事のポイント

・fioで「ディスクの実力値」を事前計測しておくと障害時の判断基準になる
・シーケンシャルはbs=1M iodepth=1、ランダムはbs=4k iodepth=32が定番パラメータ
・--direct=1を忘れるとRAMを測定してしまい、実際のディスク性能が分からない
・bw(帯域)・IOPS・clat(完了レイテンシ)の3指標を読めれば実用上十分


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

ディスクI/Oが疑われる場面とfioが必要な理由

ディスクパフォーマンスの問題はいくつかの典型的な場面で浮かび上がります。

・ピーク時間帯にWebアプリのレスポンスが急に悪化する
・MySQLのスロークエリが多発しているがクエリ内容よりI/O待ちが原因に見える
iostat -xz 1 で特定ディスクの%utilが90%を超える時間帯がある
・仮想マシンのディスクをSSDに変更したが期待ほど速くならない

こういった場面で「本当にディスクが詰まっているのか、アプリ側の問題なのか」を切り分けるには、ディスク単体の最大性能(ベンチマーク値)が必要です。ベンチマーク値がなければ、iostatの%util 80%が「通常範囲」なのか「限界間際」なのかを判断できません。

fio(Flexible I/O Tester)はLinux標準の汎用I/Oベンチマークツールです。ブロックサイズ・キュー深度・並列数・アクセスパターンを自由に組み合わせられるため、本番ワークロードに近い条件での性能計測が可能です。ディスクが本番に搬入された直後の計測、OSリプレース後の性能確認、クラウドストレージの実効帯域確認など、幅広い場面で活用されています。

fioのインストール方法

1. RHEL 9 / Rocky Linux 9 / AlmaLinux 9 の場合

# baseリポジトリに含まれているためEPEL不要 [root@server01 ~]# dnf install -y fio # インストール確認 [root@server01 ~]# fio --version fio-3.35

2. Ubuntu 24.04 LTS / Debian 12 の場合

[root@server01 ~]# apt update && apt install -y fio [root@server01 ~]# fio --version fio-3.33

計測の前に確認しておくこと

1. テスト対象のディスクを特定する

ベンチマーク前に、評価したいディスクとファイルシステムを確認します。dmidecode でハードウェア情報を取得することでディスクの種類(HDD/SSD/NVMe)やインタフェースを把握しておくと、測定値が妥当かどうかの判断基準になります。

テストファイルを置くパスは、評価したいディスク上に作成します。mount コマンドの使い方で現在のマウントポイントとファイルシステムの種類(ext4 / XFS)を確認しておきましょう。

# マウント状況を確認してテスト先を決める [root@server01 ~]# df -Th Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 3.8G 0 3.8G 0% /dev /dev/sda1 xfs 50G 12G 38G 24% / /dev/sdb1 xfs 200G 15G 185G 8% /data

この例では/data/dev/sdb1にマウント)を対象にするなら、テストファイルは/data/fio-testfileに作成します。

2. テストファイルとブロックデバイス直接指定の違い

fioのテスト対象にはテストファイル(推奨)ブロックデバイス直接の2種類があります。

テストファイル(--filename=/data/fio-testfile):既存のデータを破壊しないため安全。本番稼働中のディスクでも使える
ブロックデバイス直接(--filename=/dev/sdb):ファイルシステムのオーバーヘッドを排除した純粋な計測が可能。ただしそのデバイス上のデータをすべて上書き・消去するため、アンマウント済みの専用テストディスクにのみ使用すること

通常のサーバー運用ではテストファイルを使う方法で十分です。誤ってブロックデバイス直接指定で本番ディスクを上書きしてしまう事故が実際に起きているため、本番サーバーでは必ずテストファイル方式を選んでください。

シーケンシャル読み書きのベンチマーク

シーケンシャルアクセスは動画配信・ログ集約・バックアップのような「大きなファイルを順番に読み書きする」ワークロードの計測です。ブロックサイズ1M、iodepth=1が定番設定です。

1. シーケンシャル書き込みテスト

[root@server01 ~]# fio \ --name=seq_write \ --rw=write \ --bs=1M \ --size=2G \ --numjobs=1 \ --direct=1 \ --iodepth=1 \ --ioengine=libaio \ --filename=/data/fio-testfile \ --group_reporting seq_write: (groupid=0, jobs=1): err= 0: pid=12438: Mon Sep 14 10:00:05 2026 write: IOPS=487, BW=487MiB/s (511MB/s)(2048MiB/4205msec); 0 zone resets slat (usec): min=3, max=180, avg=14.22, stdev= 8.11 clat (usec): min=924, max=3524, avg=2035.80, stdev=202.14 lat (usec): min=930, max=3540, avg=2050.02, stdev=203.94 clat percentiles (usec): | 1.00th=[ 1582], 5.00th=[ 1729], 50.00th=[ 2024], 99.00th=[ 2507] iops : min= 408, max= 504, avg=487.40, stdev=19.32, samples=8 Run status group 0 (all jobs): WRITE: bw=487MiB/s (511MB/s), io=2048MiB (2148MB), run=4205-4205msec

この例ではシーケンシャル書き込みが約487MB/sです。一般的なSATA SSDは500~600MB/s、NVMe SSDは2,000~7,000MB/s、HDDは100~200MB/sが目安なので、このサーバーのディスクはSATA SSD相当の性能と推測できます。

2. シーケンシャル読み込みテスト

[root@server01 ~]# fio \ --name=seq_read \ --rw=read \ --bs=1M \ --size=2G \ --numjobs=1 \ --direct=1 \ --iodepth=1 \ --ioengine=libaio \ --filename=/data/fio-testfile \ --group_reporting seq_read: (groupid=0, jobs=1): err= 0: pid=12512: read: IOPS=489, BW=489MiB/s (513MB/s)(2048MiB/4188msec) clat (usec): min=908, max=4102, avg=2040.12, stdev=215.34 iops : min= 412, max= 510, avg=490.20, stdev=19.51, samples=8 Run status group 0 (all jobs): READ: bw=489MiB/s (513MB/s), io=2048MiB (2148MB), run=4188-4188msec

書き込みと読み込みで同程度(487 vs 489 MiB/s)なのはSSDとしては自然な特性です。HDDでは回転待ちが発生するためシーケンシャルでも数値のばらつきが大きくなります。

ランダム読み書きのベンチマーク(4K)

ランダムアクセスはMySQL・PostgreSQL・メールサーバーのような「小さなブロックを非連続に読み書きする」ワークロードの計測です。ブロックサイズ4k、numjobs=4、iodepth=32が定番設定です。

1. ランダム4K書き込みテスト

[root@server01 ~]# fio \ --name=rand_write \ --rw=randwrite \ --bs=4k \ --size=2G \ --numjobs=4 \ --direct=1 \ --iodepth=32 \ --ioengine=libaio \ --filename=/data/fio-testfile \ --group_reporting rand_write: (groupid=0, jobs=4): err= 0: pid=12605: write: IOPS=41.5k, BW=162MiB/s (170MB/s)(2048MiB/12625msec) slat (nsec): min=1460, max=98010, avg=5224.37, stdev=3105.92 clat (usec): min=278, max=48219, avg=3072.88, stdev=2145.33 clat percentiles (usec): | 1.00th=[ 604], 5.00th=[ 668], 50.00th=[ 2900], 99.00th=[ 9503] | 99.99th=[35390] iops : min=32768, max=44128, avg=40579.42, stdev=1956.57, samples=100 Run status group 0 (all jobs): WRITE: bw=162MiB/s (170MB/s), io=2048MiB (2148MB), run=12625-12625msec

2. ランダム4K読み込みテスト

[root@server01 ~]# fio \ --name=rand_read \ --rw=randread \ --bs=4k \ --size=2G \ --numjobs=4 \ --direct=1 \ --iodepth=32 \ --ioengine=libaio \ --filename=/data/fio-testfile \ --group_reporting rand_read: (groupid=0, jobs=4): err= 0: pid=12714: read: IOPS=87.2k, BW=341MiB/s (357MB/s)(2048MiB/6014msec) clat (usec): min=212, max=16584, avg=1459.84, stdev=876.42 clat percentiles (usec): | 1.00th=[ 318], 5.00th=[ 437], 50.00th=[ 1270], 99.00th=[ 4293] | 99.99th=[12648] iops : min=67424, max=100032, avg=87206.36, stdev=5834.10, samples=24 Run status group 0 (all jobs): READ: bw=341MiB/s (357MB/s), io=2048MiB (2148MB), run=6014-6014msec

読み込みIOPS(87,200)が書き込みIOPS(41,500)の約2倍になっています。SSDでは書き込みに内部的なウェアレベリング処理が入るため、書き込みが読み込みより遅くなるのは正常な特性です。

fio出力の読み方(bw・IOPS・clatの3指標)

1. bw(帯域幅)

bw=487MiB/sのように表示されるのが帯域幅(スループット)です。「1秒間に何バイト転送できたか」を示します。

・シーケンシャルアクセスでは帯域幅がボトルネックになりやすい(大容量ファイルの書き出しなど)
・ランダムアクセスでは後述のIOPSの方が重要な指標になる場合が多い
・単位は「KiB/s」または「MiB/s」。MB/s(メガバイト毎秒)とMiB/sは1.048576倍の差があるため、カタログスペックと比較するときは注意する

2. IOPS(秒間I/O処理数)

IOPS=41.5kのように表示されるのがI/O operations per secondです。「1秒間に何回のI/Oリクエストを処理できたか」を示します。

・データベースのパフォーマンスはIOPSに支配されることが多い(MySQLの4Kランダム読み書き等)
・HDDは100~200 IOPS、SATA SSDは40,000~100,000 IOPS、NVMe SSDは200,000~1,000,000 IOPSが目安
・iodepthやnumjobsを増やすとIOPSが上がる場合があるが、ある値を超えるとCPU・カーネルがボトルネックになって頭打ちになる

3. clat(completion latency・完了レイテンシ)

clat (usec): avg=3072.88のように表示されるのが完了レイテンシです。「I/Oリクエストを出してから完了するまでの時間」をマイクロ秒(usec)で示します。

・アプリケーションが体感する応答速度に直結する指標
・99パーセンタイル(99.00th)の値を見ることで外れ値の影響を把握できる
slat(submission latency)はカーネルへのI/O投入にかかる時間で、通常はマイクロ秒以下
lat(total latency)= slat + clat の合計値

SSDでランダム読み込みのclat avgが1,000~2,000usec(1~2ms)であれば正常範囲です。HDDでは回転待ちがあるため5,000usec以上になることもあります。

重要オプションの早見表

オプション 意味 推奨値・注意点
fio --name=... --direct=1 OSページキャッシュをバイパスして直接I/O 常に指定する。省略するとRAMのキャッシュを測ることになり、実ディスク性能が分からない
fio --name=... --ioengine=libaio Linuxカーネルの非同期I/Oエンジンを使用 Linuxサーバーの推奨値。デフォルトのposixaioより高スループット
fio --name=... --bs=N ブロックサイズ シーケンシャルテストは1M、ランダムテストは4k
fio --name=... --iodepth=N キュー深度(未完了I/Oの最大同時発行数) シーケンシャルは1、ランダムは32が定番。NVMe SSDは128以上でさらに伸びることがある
fio --name=... --numjobs=N 並列ワーカー数 1~CPUコア数。多すぎるとCPUがボトルネックになる
fio --name=... --runtime=N --time_based 測定時間を秒で指定(サイズでなく時間で制御) 60~300秒で安定した平均値が得やすい
fio --name=... --size=N 各ワーカーのI/O量(またはテストファイルサイズ) 実メモリより大きいサイズを指定するとキャッシュ汚染を防げる

ジョブファイルで再現性のあるテストを管理する

コマンドラインが長くなる場合はジョブファイル(.fio)にまとめると管理しやすく、バージョン管理にも置きやすくなります。

1. ジョブファイルの作成

[root@server01 ~]# cat /etc/fio/diskbench.fio [global] ioengine=libaio direct=1 runtime=60 time_based=1 group_reporting=1 filename=/data/fio-testfile [seq-write-1M] rw=write bs=1M numjobs=1 iodepth=1 [seq-read-1M] rw=read bs=1M numjobs=1 iodepth=1 [rand-write-4k] rw=randwrite bs=4k numjobs=4 iodepth=32 [rand-read-4k] rw=randread bs=4k numjobs=4 iodepth=32

2. ジョブファイルを実行する

# ジョブを順番に実行([global]の設定が各セクションに引き継がれる) [root@server01 ~]# fio /etc/fio/diskbench.fio # 特定のセクションだけ実行したい場合 [root@server01 ~]# fio /etc/fio/diskbench.fio --section=rand-read-4k # 結果をJSONで保存(ディスク交換前後の比較に便利) [root@server01 ~]# fio /etc/fio/diskbench.fio --output=result_20260914.json --output-format=json

ジョブファイルをサーバー構成管理(Ansible/gitリポジトリ)に入れておくと、ディスク交換前後の性能比較や定期的なパフォーマンス記録が容易になります。

トラブルシュート:iostatとの組み合わせで高負荷を診断する

fioのベンチマーク値を基準にして、本番稼働中のiostat実測値と比較するのが高負荷診断の定石です。

1. 別ターミナルでiostatをリアルタイム監視する

# 1秒間隔でsdb(データディスク)の詳細統計を表示 [root@server01 ~]# iostat -xz 1 sdb Linux 5.14.0-427.13.1.el9_4.x86_64 09/14/2026 _x86_64_ Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s r_await w_await aqu-sz %util sdb 82400.0 0.0 329600.0 0.0 0.0 0.0 0.94 0.00 0.08 93.00

2. iostat出力で確認すべき3指標

%util:ディスクがビジー状態だった時間の割合。80%を超えると要注意。100%に張り付いていれば飽和(I/O待ちが発生してアプリに影響が出ている状態)
r_await / w_await:読み書きI/Oリクエストの平均待ち時間(ミリ秒)。SSDで平均10ms超はストレージ問題の可能性。HDDでは10~20msが正常範囲
aqu-sz:平均キューサイズ。大きいほどI/Oが滞留している。SSDで1を大きく超えている場合はIOPS上限に近い

fioベンチマーク値との組み合わせ診断例:

fioで計測したランダム読み込みIOPSが87,000 IOPS(最大)だとします。iostatで本番稼働中のr/sが82,400まで上がっているなら、ディスクの限界に近いと判断できます。一方でr/sが30,000程度で%utilが90%になっている場合は、ディスクの飽和ではなくホストのI/Oスケジューラ・VMのストレージ割り当て側の問題を疑うべきです。

ベンチマーク値なしでiostatの数値だけ見ていると「%util 90%だからディスク交換しよう」という誤判断をしがちです。fioで実力値を把握しておくことで、交換・増強が本当に必要かどうかの根拠を持った判断が可能になります。

本記事のまとめ

測定目的 コマンドの例
シーケンシャル書き込み帯域 fio --name=seq_write --rw=write --bs=1M --size=2G --numjobs=1 --direct=1 --iodepth=1 --ioengine=libaio --filename=/data/fio-testfile
シーケンシャル読み込み帯域 fio --name=seq_read --rw=read --bs=1M --size=2G --numjobs=1 --direct=1 --iodepth=1 --ioengine=libaio --filename=/data/fio-testfile
ランダム4K書き込みIOPS fio --name=rand_write --rw=randwrite --bs=4k --size=2G --numjobs=4 --direct=1 --iodepth=32 --ioengine=libaio --filename=/data/fio-testfile
ランダム4K読み込みIOPS fio --name=rand_read --rw=randread --bs=4k --size=2G --numjobs=4 --direct=1 --iodepth=32 --ioengine=libaio --filename=/data/fio-testfile
ジョブファイルで複数テストを一括実行 fio /etc/fio/diskbench.fio --output=result.json --output-format=json
特定セクションだけ実行 fio /etc/fio/diskbench.fio --section=rand-read-4k
fioで「ディスクの実力値」を把握しておくことが、本番障害時の「ディスク限界か、アプリ問題か」の判断を速くします。サーバー納品直後や仮想マシンのディスク変更後に1回計測するだけで、以降の障害対応で根拠ある判断ができるようになります。

ディスクI/Oのボトルネック診断スキルを固めたら、次はLinuxサーバー全体の構築・運用スキルを体系的に身につけませんか?

fioで実力値を計測し、iostatで現場を診断できるのは、Linuxのストレージ構造を理解しているエンジニアだけです。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。