磁盘 IO 性能基准测试指南(fio)
使用 fio 对磁盘进行随机读写、顺序读写、混合负载基准测试,记录 IOPS 与延迟基线,详解 fio 核心参数、单向/多向混合 job 编写与结果解读,含 Ubuntu 22.04 fio 3.28 实测回显。
磁盘 IO 性能基准测试指南(fio)
目标:使用 fio 对磁盘进行随机读写、顺序读写、混合负载测试,获取 IOPS、带宽(BW)与延迟基线,为容量规划与性能对比提供量化依据。核心命令 fio(libaio 引擎、
direct=1绕过页缓存)。本文在 Ubuntu 22.04(fio-3.28)实测。
环境信息
- 操作系统:Ubuntu 22.04.5 LTS;fio 版本:3.28
- 引擎:libaio(Linux 原生异步 IO)
- 实测单队列随机读示例:
IOPS=25.1k, BW=98.1MiB/s (103MB/s),clat 平均 ~1.27ms
前置条件
- root 权限(direct io 写测试会覆盖目标文件)。
- 安装 fio:
apt-get install -y fio。 - ⚠️ 在未被挂载的分区测试最准;对已有数据目录测试会破坏该目录文件,务必指定独立的测试文件路径。
fio 核心参数说明
| 参数 | 说明 |
|---|---|
--rw | 读写模式:read/write/randread/randwrite/rw/randrw |
--bs | 块大小,如 4k、1M |
--ioengine | IO 引擎:libaio(推荐)、sync、psync |
--iodepth | 队列深度(in-flight 请求数),libaio 常用 32 |
--numjobs | 并行 job 数 |
--size | 每个 job 的总数据量,建议 ≥ 2x 内存尺寸 |
--direct=1 | 绕过页缓存直接写设备,结果更贴近真实 |
--runtime | 测试时长,配合 --time_based 按时间取样 |
--group_reporting | 聚合多 job 数据,输出汇总 |
--name | job 名称(输出标识) |
💡 说明:
--direct=1是关键,否则写操作先落到页缓存,测试的是内核缓存而非磁盘真实能力。
1. 随机读写测试(IOPS)
# 随机读(4K,深度 32)
fio --name=randread --ioengine=libaio --rw=randread --bs=4k \
--size=1G --numjobs=1 --iodepth=32 --runtime=10 --time_based \
--direct=1 --group_reporting
实测关键输出(部分):
read: IOPS=25.1k, BW=98.1MiB/s (103MB/s)(393MiB/4001msec)
slat (usec): min=3, max=1435, avg=37.15
clat (usec): min=93, max=6349, avg=1235.37
lat (usec): min=129, max=6400, avg=1272.68
# 随机写(4K)
fio --name=randwrite --ioengine=libaio --rw=randwrite --bs=4k \
--size=1G --numjobs=1 --iodepth=32 --runtime=10 --time_based \
--direct=1 --group_reporting
指标解读:IOPS 反映每秒请求数(随机小 IO);
clat/lat的 avg/percentiles 反映延迟分布。
2. 顺序读写测试(带宽 BW)
# 顺序读(1M,测量带宽)
fio --name=seqread --ioengine=libaio --rw=read --bs=1M \
--size=2G --iodepth=32 --runtime=10 --time_based --direct=1 --group_reporting
# 顺序写
fio --name=seqwrite --ioengine=libaio --rw=write --bs=1M \
--size=2G --iodepth=32 --runtime=10 --time_based --direct=1 --group_reporting
3. 混合负载测试(randrw)
用 job 文件定义读/写比例(如 70% 读 + 30% 写):
# -rw=randrw,default 读写比 50:50;用 rwmixread 指定读比例
fio --name=mixed --ioengine=libaio --rw=randrw --rwmixread=70 \
--bs=8k --size=1G --iodepth=16 --numjobs=4 \
--runtime=15 --time_based --direct=1 --group_reporting
混合输出会同时给出 READ 与 WRITE 两个块的 IOPS/BW 与 lat。
4. 使用 job 文件(可复现、带注释)
/tmp/rwtest.fio:
# 随机读写混合测试
[global]
ioengine=libaio
direct=1
runtime=20
time_based=1
group_reporting=1
size=1G
[randread-8k]
rw=randread
bs=8k
iodepth=32
numjobs=1
filename=/tmp/fio.randread
[randwrite-8k]
rw=randwrite
bs=8k
iodepth=32
numjobs=1
filename=/tmp/fio.randwrite
运行:
fio /tmp/rwtest.fio
5. 结果记录与基线管理
将关键指标记入基线表后再优化对比:
| 场景 | 块大小 | IOPS | BW | avg lat | p99 lat |
|---|---|---|---|---|---|
| 随机读 | 4K | 25.1k | 98.1MiB/s | 1.27ms | <4ms |
| 随机写 | 4K | 待测 | — | — | — |
| 顺序读 | 1M | — | 待测 | — | — |
💡 说明:建议多次取平均并在同样负载、同样路径(/tmp vs 真实分区)下对比,才具有可比性。生产容量评估还应结合 iostat 在持续负载下的 %util 与 await。
常见问题
Q:为什么 direct=1 下 IOPS 明显低于默认?
A:默认进页缓存,命中率高但非真实磁盘能力;direct=1 绕过缓存,反映设备真实随机 IO 能力。
Q:ioengine=libaio 提示无法打开?
A:老内核需确认 CONFIG_AIO 已启用;生产 Ubuntu 22.04 默认可用。也可改用 psync/sync。
Q:测试写会破坏数据吗?
A:会覆盖 filename 指定的文件/分区。务必用独立测试文件或空分区,禁止在生产数据目录上跑写测试。
卸载方式
删除测试产生的临时文件(如 /tmp/fio.*)即可;fio 无需常驻服务。
参考链接
- fio 官方文档:
/usr/share/doc/fio/examples/、man fio - 在线 HOWTO:
https://fio.readthedocs.io/en/latest/fio_doc.html