iostat -dx 1是唯一能直接抓取瞬时磁盘读写峰值的命令,因其每秒刷新、显示绕过page cache的rkB/s/wkB/s真实吞吐,且-d屏蔽CPU、-x启用关键字段;其他工具或采样过慢、或统计口径失真,易漏掉毫秒级尖峰。

iostat -dx 1 是唯一能直接抓到瞬时磁盘读写峰值的命令,其他工具要么采样太慢、要么统计口径不对,容易漏掉真实尖峰。
为什么必须用 iostat -dx 1 看峰值
磁盘读写峰值是毫秒级突发行为,不是平均值。默认 iostat 或只加 -d 的输出里,r/s 和 w/s 是上层合并后的逻辑请求数,在 NVMe、virtio 或开启 IO 调度器时可能比真实下发请求少一个数量级;不带 -x 就看不到 rkB/s 和 wkB/s 这两个关键瞬时吞吐字段。
-
-d:屏蔽 CPU 行,专注磁盘设备 -
-x:启用扩展指标,暴露rkB/s、wkB/s、r_ios、w_ios -
1:每秒刷新一次——间隔大于 1 秒会漏掉尖峰,小于 1 秒(如 0.1)会导致终端刷屏且无实际分辨力
峰值就藏在滚动输出中跳得最高的那几行 rkB/s 或 wkB/s 值里,单位是 KB/s,直接对应物理层绕过 page cache 的真实读写速率。
怎么聚焦目标设备,避免被空闲盘干扰
如果系统有多个磁盘(比如 /dev/sda、/dev/nvme0n1),不加限定会混在一起看,峰值容易被低速盘拉低或掩盖。
- 查单块盘:
iostat -dx 1 /dev/sdb—— 只显示sdb的实时数据 - 查 LVM 或分区:
iostat -dx 1 -p ALL—— 输出包含sdb1、dm-0等子设备,方便定位具体逻辑卷 - 查 NVMe 多队列设备:
iostat -dx 1 /dev/nvme0n1,注意它的%util接近 100% 不代表瓶颈,要结合r_await > 20ms和rkB/s是否冲到理论带宽 80% 以上综合判断
怎么知道是谁在制造峰值
iostat 告诉你“哪块盘在狂读”,但不告诉你“谁干的”。这时候必须切进程维度,pidstat -d 1 是唯一能给出按 PID 拆分的瞬时 rkB/s 和 wkB/s 的工具。
- 必须带采样间隔:
pidstat -d 1,单独执行pidstat -d会立即退出,看不到变化 - 别用
pidstat -d 0:内核疯狂上报,终端卡死,甚至触发 OOM - 精准锁定进程:
pidstat -d 1 -p "$(pgrep -f 'redis-server')",比ps aux | grep抗干扰强得多 - 注意线程/进程切换:按快捷键
p可在 TID 和 PID 视图间切换,避免把一个 Java 进程的多个 GC 线程当成多个独立高读源
为什么 iotop -o 容易错过峰值
iotop 界面友好,但它的设计和“峰值观测”天然冲突:-o 参数只显示“当前有 IO 活动”的进程,而真实业务中一次大读往往由单次系统调用(比如 mmap + readahead)触发,持续几十毫秒就结束。iotop 默认每秒刷新一次,大概率刚好错过。
它显示的 DISK READ 和 DISK WRITE 本质是 /proc/[pid]/io 中的 rchar/wchar,含 page cache 命中,不是真实磁盘读写量;想看真实归属,还是得靠 pidstat -d 1 的 rkB/s 列(基于 read_bytes 计算)。


















