fio随机读写测试需加--direct=1绕过page cache、--iodepth控制队列深度、--bs=4k测iops,配--time_based--runtime=60和--size=10g防缓存干扰;输出曲线须用--write_iops_log与--write_lat_log生成时序日志,再清洗绘图。

fio 随机读写测试命令怎么写才不跑偏
直接用 fio 跑随机读写,十次有八次测出来的是缓存数据或队列堆积结果,不是磁盘真实能力。关键在绕过 page cache、控制队列深度、固定 IO size 和模式。
- 必须加
--direct=1,否则 Linux 会把大部分 IO 拦在 page cache 里,randread可能全走内存 - 用
--iodepth=32模拟高并发场景,但别盲目堆高——NVMe 盘可设到 64,SATA SSD 超过 16 就容易掩盖延迟差异 -
--bs=4k是测 IOPS 的黄金值;想看吞吐就换--bs=128k或--bs=1m,但两者不能混在同一轮测试比 - 加
--time_based --runtime=60,避免因文件大小不足提前退出;同时配--size=10g(至少 2 倍于 RAM)防 swap 干扰
怎么让 fio 输出能直接画 IOPS 和延迟曲线
fio 默认输出是人眼友好型汇总,没法直接喂给 gnuplot 或 pandas。得靠 --output-format=json + 后处理,但注意默认 JSON 不含逐秒明细。
- 加
--write_iops_log=iops --write_lat_log=lat --log_avg_msec=1000,生成两个日志:每秒平均 IOPS 和每秒平均延迟(单位微秒) - 生成的
iops.log是纯文本,三列:时间戳、IOPS、带宽(KB/s);lat.log第三列是延迟(微秒),别误当成毫秒 - 如果要亚秒级分辨率(比如看 burst 行为),把
--log_avg_msec=1000改成100,但日志体积暴涨,SSD 测 60 秒可能出 600 行 - 别用
--minimal输出——它压根不记录时间序列,只给最终均值
gnuplot 绘制延迟曲线时常见坐标错乱
直接用 lat.log 画图,经常发现 X 轴是乱序时间戳、Y 轴数值跳变巨大,其实是 log 文件里有空行或头尾非数据行。
- 先清洗:
grep -v "^#" lat.log | awk '$3 > 0 && $3 lat_clean.dat(过滤掉注释、异常大延迟) - gnuplot 中 Y 轴建议用对数刻度:
set logscale y,因为随机读延迟常跨 3 个数量级(几十μs 到几 ms) - 如果用
smooth csplines插值,会平滑掉真实毛刺;真要看瞬时抖动,就用with lines原样连点 - 别漏掉单位标注:
set ylabel "Latency (μs)",μ 是μ,不是 u 或 mu
多线程/多 job 下 IOPS 算术叠加为什么不准
两个 --numjobs=4 的 job 并发跑,总 IOPS 不是单个 job 的 2 倍——尤其在 SATA 盘或低队列深度下,控制器争抢会让实际吞吐塌缩。
- 验证方法:分别跑
--numjobs=1、2、4,看 IOPS 是否线性增长;若 4 线程只比 2 线程高 10%,说明瓶颈在硬件层 -
--group_reporting必须开启,否则每个 job 单独输出,sum 时容易漏算或重复算 - 混合读写(
--rw=randrw --rwmixread=70)时,fio默认按字节比例混合,但 IOPS 计算仍分读/写两列,别直接加总 - 用
--name给每个 job 打标,比如--name=read-4k-qd32,否则多个 job 日志混在一起根本分不清谁是谁
真正难的不是跑出数字,而是让每次测试的变量可控——同一块盘,换一个 --ioengine(比如 libaio vs sync),延迟分布可能完全两样,但很多人根本没意识到自己在测引擎而非磁盘。










