fio 磁盘 IO 压测:iodepth、numjobs 与 ioengine
更新时间:2026-09-19。fio(Flexible I/O Tester)是最常用的磁盘/文件系统基准工具,能精确控制负载类型。测真实磁盘性能务必绕过页缓存(
direct=1),否则测的是内存速度。清缓存做冷读见 drop_caches,线上实时观察用 iostat/iotop。
一、四个关键参数
| 参数 | 含义 |
|---|---|
rw | 负载:randread/randwrite/read(顺序读)/write/randrw(混合) |
bs | 块大小:4k(数据库随机)、128k/1m(顺序吞吐) |
iodepth | 每个 job 在飞的 I/O 数(队列深度,QD) |
numjobs | 并发线程/进程数(模拟多客户端) |
ioengine | I/O 提交方式:libaio(Linux 异步)、io_uring(新)、psync(同步) |
direct | 1=绕过页缓存(O_DIRECT),测真实设备 |
runtime/time_based | 限时跑;rwmixread 混合读写比例 |
iodepth 与 numjobs 的区别:iodepth 是单线程异步并发(一个 job 同时挂多少 I/O),测的是设备队列能力;numjobs 是多个线程,测的是多客户端聚合。单 job iodepth=32 和 numjobs=32, iodepth=1 压力形态不同,前者更像深队列吞吐,后者更像并发小请求。
二、常用可复现命令
bash
# 1) 随机读 IOPS(4K,libaio,深队列),最常用于数据库场景
fio --name=randread --filename=/data/fio.test --rw=randread --bs=4k --ioengine=libaio --iodepth=32 --numjobs=4 --direct=1 --runtime=60 --time_based --group_reporting --size=1G
# 2) 随机写(测写 IOPS 与写延迟,注意会写数据,务必用测试文件/空闲盘)
fio --name=randwrite --filename=/data/fio.test --rw=randwrite --bs=4k --ioengine=io_uring --iodepth=16 --numjobs=4 --direct=1 --runtime=60 --time_based --group_reporting
# 3) 顺序读带宽(1M 大块,看 BW 吞吐,对应大文件/流媒体)
fio --name=seqread --filename=/data/fio.test --rw=read --bs=1m --ioengine=libaio --iodepth=8 --numjobs=1 --direct=1 --runtime=60 --time_based --group_reporting
# 4) 同步引擎模拟应用多线程小 IO(psync,iodepth 基本无效)
fio --name=app --filename=/data/fio.test --rw=randrw --rwmixread=70 --bs=4k --ioengine=psync --numjobs=16 --direct=1 --runtime=60 --time_based --group_reporting三、结果怎么读
bash
read: IOPS=24.3k, BW=95.0MiB/s (99.6MB/s)
lat (usec): min=..., avg=120, stdev=..., p99=480, p99.9=1200
cpu: ...
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=..., 32=72% # 实际队列深度分布- IOPS:随机小 IO 的核心指标(4K randread/randwrite)。
- BW:顺序大块的吞吐(MB/s)。
- avg / p99 / p99.99 lat:延迟分布;P99 比 avg 更能反映尾部抖动,见分位数。
- IO depths 分布:确认 iodepth 是否真打上去了;若一直停在 1,说明引擎/参数没产生并发(常见于 psync 配 iodepth)。
- iodepth 饱和曲线:1→2→4→8→16→32→64 阶梯测,IOPS 见顶而 P99 开始暴涨的点,就是设备/队列的实用拐点。
四、怎么设计测试
- 贴近真实负载:数据库用 4k/8k 随机、70/30 混合;日志/备份用大块顺序;别用一个数值代表所有场景。
- direct=1 + 足够 size:绕过缓存,文件要大于缓存容量,否则结果虚高。
- 先预热:SSD 尤其有缓存/SLC 模式差异,短测会虚高,持续跑几分钟看稳定段。
- 分清设备与文件系统:裸盘(
--filename=/dev/nvmeXnY)测硬件,带目录测文件系统+挂载选项;写裸盘会摧毁数据。 - 同时观测:另一终端跑 iostat 看
%util/await/aqu-sz,验证 fio 压力与内核视角一致。
坑
- 不加
direct=1,命中页缓存,测出几十 GB/s 的「内存性能」。 - 在生产盘上跑 randwrite/写裸设备,直接毁数据;只能用专用测试文件或空闲盘。
- psync 引擎配高 iodepth 以为有并发,实际深度恒为 1。
- numjobs×iodepth 远超设备能力,P99 延迟爆炸却只报平均 IOPS。
- SSD 短测虚高(缓存效应),结论不稳定;要 runtime 足够并关注长期稳态。
文件系统级负载建模可进一步用 filebench。
总结
fio 通过 rw 选择顺序或随机、bs 匹配 4K 数据库小块或 1M 大块,用 iodepth 控制单 job 异步队列深度、numjobs 模拟并发客户端,配合 libaio/io_uring 引擎和 direct=1 绕过页缓存测真实设备;读结果关注 IOPS、BW、avg/P99 延迟和实际队列深度分布,并按 iodepth 阶梯找吞吐见顶而尾延迟飙升的拐点;测试要贴近真实读写比例、充分预热、绝对避免在生产盘写测,并用 iostat 交叉验证。