iostat -x 是查看真实 iops 和吞吐量的唯一合理起点,因其输出的 r_ios/w_ios 表示实际下发到设备的读写次数,rmb/s/wmb/s 为绕过 page cache 的真实吞吐,而普通 iostat 的 r/s、w/s 因请求合并等失真。

iostat 是最直接、最可靠的 Linux 磁盘 IOPS 和吞吐量观测工具,但默认输出不显示 IOPS —— 必须加 -x 选项才能看到关键指标。
为什么 iostat -x 是查看 IOPS 的唯一合理起点
普通 iostat 只显示 r/s(每秒读请求数)和 w/s(每秒写请求数),但这俩数值在现代存储栈(尤其是带缓存、队列合并、多路径或 virtio 层的环境)中严重失真。只有 iostat -x 输出的 r_ios/w_ios(实际下发到设备的读/写 I/O 次数)才接近真实 IOPS。而吞吐量必须看 rMB/s 和 wMB/s,它们是绕过 page cache 后、真正落到块设备的数据速率。
-
iostat -x 1 3:每秒刷新一次,共 3 次,跳过首行“冷启动”噪音 - 重点关注字段:
r_ios、w_ios(IOPS)、rMB/s、wMB/s(吞吐)、%util(利用率)、await(平均等待毫秒) - 如果
%util接近 100% 且await显著升高,说明 I/O 队列积压,不是设备快慢问题,而是并发或调度瓶颈
iostat -x 输出中哪些字段对应真实 IOPS 和吞吐
别被 rkB/s 和 wkB/s 迷惑——它们是旧单位、未归一化,且不含请求计数;r/s 和 w/s 是上层 IO 栈(如 VFS 或 block layer)统计的逻辑请求,会被合并、重排、延迟下发,不能当 IOPS 用。
- 真实 IOPS 来自
r_ios(读 I/O 次数)和w_ios(写 I/O 次数):这两个值由底层驱动直接上报,代表真正发给物理设备或 virtio queue 的请求个数 - 真实吞吐来自
rMB/s和wMB/s:单位统一为 MB,已排除缓存干扰,与存储厂商标称吞吐可比 -
avgrq-sz是平均请求大小(扇区数),可粗略验证:若r_ios×avgrq-sz× 512 ≈rkB/s× 1024,则数据链路一致;否则说明有压缩、去重或协议开销(如 NVMe 多队列、virtio-blk 协议头)
常见误判场景:iostat 显示高 IOPS 但业务卡顿
这不是 iostat 出错,而是你没结合上下文读指标。高 r_ios + 高 await + 高 %util ≠ 磁盘慢,很可能是小 IO(4K/8K)随机访问压垮了队列深度或介质响应能力。
- 检查
avgrq-sz:若长期 - 对比
r_ios和rrqm/s(读请求合并数):若rrqm/s占比高,说明上层合并有效;若几乎为 0,说明 IO 是分散的、不可合并的随机访问 - 注意
iostat -x不区分进程来源——要定位谁在刷盘,得配合iotop -oP或pidstat -d 1 - 云环境(如 KVM/virtio)下,
iostat -x的r_ios/w_ios是 guest kernel 下发到 virtio queue 的次数,不等于物理 SSD 的实际 NAND 操作次数(后者需宿主机侧virtiostat或perf观测)
什么时候不该信 iostat -x 的数值
iostat -x 值得信赖的前提是:IO 路径干净、无中间缓存污染、设备驱动正确上报。一旦打破这些,数值就只是参考。
- 使用 LVM thin pool、ZFS、btrfs 的压缩/去重功能时:
r_ios仍是 guest 侧请求数,但物理写入量远小于wMB/s,此时吞吐指标失真 - 挂载选项含
barrier=0、commit=60或 ext4 的data=writeback:写 IOPS(w_ios)会骤降,因为大量 write 被延迟合并或跳过日志,但数据一致性风险上升 - SSD 后台 GC 活跃期:
iostat看不到 GC 引起的内部写放大,r_ios/w_ios低估真实介质压力 - 容器环境(如 Docker overlay2):
iostat统计的是 host device,无法反映某容器内应用的 IO 分布,需用cgroup v2 io.stat补充
真实 IOPS 和吞吐永远依赖观测点位置——iostat -x 看的是块设备入口,离应用越远,越难解释业务行为。别只盯着一个数字,要连 await、svctm(已弃用,但 svctm 仍说明排队存在)、<code>%util 一起读。











