直接用 iostat -x 1 查看实时 iops(r/s + w/s)和吞吐量(rkb/s + wkb/s,除以1024得mb/s),%util 不能单独判断瓶颈,需结合 await、队列长度等综合分析。

怎么看当前磁盘的实时 IOPS 和吞吐量
直接用 iostat -x 1,别绕弯。它输出里关键字段就三个:r/s 和 w/s 是每秒读、写请求数(即 IOPS),rkB/s 和 wkB/s 是每秒读、写千字节数(即吞吐量,除以 1024 得 MB/s)。
常见误区是盯着 %util 看——它只反映设备忙闲比例,不是性能瓶颈的充分条件。SSD 上 %util 刚过 50% 就可能因队列深度不足卡住;而机械盘即使 %util 95%,IOPS 也可能只有几百。
-
iostat -x 1默认单位是 kB,加-h可自动换算成 MB/GB,但字段名不会变(仍是rkB/s) - 如果
r/s很高但rkB/s很低,说明是小块随机读(如数据库索引扫描) - 如果
await明显高于svctm(后者已弃用,仅作参考),说明请求在队列里排队了,不是设备处理慢
fio 测试时 rw=randread 和 rw=read 的区别很关键
rw=randread 是随机读,地址跳着来;rw=read 是顺序读,地址线性推进。两者对磁盘压力完全不同:SSD 在随机读下 IOPS 高但吞吐未必高,HDD 则可能因寻道时间暴涨导致 IOPS 断崖下跌。
实际测试中,必须按业务场景选模式。比如 PostgreSQL 默认 8KB 页面,bs=8k + rw=randread 才接近真实负载;而备份工具走的是大块顺序流,该用 bs=1M + rw=read。
-
randread/randwrite默认按逻辑块地址(LBA)随机,不保证跨文件系统或跨分区均匀,若需更真实模拟,加norandommap参数避免重复打同一区域 -
read/write模式下,fio 会尽量连续分配空间,但若测试文件已存在且碎片化,结果仍可能偏保守 - 混合读写用
rw=randrw,rwmixread=70表示 70% 读 + 30% 写,不是简单交替
fio 的 direct=1 和 sync=1 不是一个东西
direct=1 绕过 page cache,让数据直通设备层,测的是纯磁盘能力;sync=1 强制每次 IO 后调用 fsync(),确保数据落盘,测的是带持久化保障的延迟(比如数据库事务提交路径)。
漏掉 direct=1 会导致测试结果虚高——缓存把反复读变成内存操作;漏掉 sync=1 则无法反映写入持久化的开销,尤其在使用 write-back cache 的 RAID 卡上,延迟可能差一个数量级。
- SSD 测试建议同时开
direct=1和sync=1,否则latency字段没意义 -
sync=1会显著降低吞吐量,但iops值更贴近 WAL 写入等强一致性场景 - 某些 NVMe 设备在
sync=1下触发 controller flush,需确认固件是否支持flush命令
dd 测出来的数字为什么和 fio 差一倍以上
因为 dd 是单线程、单请求、阻塞式 IO,而 fio 默认多线程并发(numjobs=1 才等效于 dd)。一块 SATA SSD 在 numjobs=4、bs=4k 下 IOPS 可达 30K,但 dd 最多跑出 1K~2K —— 它根本压不起来设备并行能力。
dd 唯一适合的场景是粗略验证写入链路是否通畅,比如检查新挂载的 LVM 卷能否写满、确认 oflag=direct 是否生效。真要压测,dd 的结果连参考价值都有限。
-
dd if=/dev/zero of=testfile bs=1M count=1024 oflag=direct测的是顺序写吞吐,不是 IOPS -
dd if=testfile of=/dev/null iflag=direct测的是顺序读吞吐,受预读影响大,加iflag=direct,noreadahead更准(部分内核支持) - fio 能控
iodepth(队列深度),这是影响 NVMe 性能的关键参数,dd 完全没法调
真正难的不是跑出数字,而是让测试逼近你线上服务的真实 IO 模式:块大小、读写比例、随机/顺序倾向、是否同步落盘、并发线程数——少设对一个,结果就可能和生产隔了一条河。











