iostat -dx 1是唯一能抓到真实读写峰值的方式,因其从块设备驱动层直接取数,rkB/s和wkB/s为绕过page cache的真实吞吐,每秒刷新可捕获瞬时尖峰,而其他工具或统计层过高、或刷新逻辑不匹配,易漏掉几十毫秒级大读调用。

直接用 iostat -dx 1 滚动观察 rkB/s 和 wkB/s 的瞬时跳变,峰值就是它们在几秒内冲到的最高值;想确认是否真实落到物理介质,必须同步看 r_ios/w_ios 和 /sys/block/sda/stat 第1/5列。
为什么 iostat -dx 1 是唯一能抓到真实读写峰值的方式
其他工具要么统计层太靠上(如 dstat、vmstat),要么刷新逻辑不匹配(如 iotop -o 每秒只采一次,极易错过几十毫秒级的大读调用)。iostat -dx 1 从块设备驱动层直接取数,rkB/s 和 wkB/s 是绕过 page cache 的真实吞吐(单位 KB/s),每秒刷新一次,足够捕获典型业务中的尖峰。
- 必须加
-d:否则默认输出含 CPU 行,干扰判断 - 必须加
-x:不加就看不到rkB/s、wkB/s、r_ios等关键字段 - 间隔设为
1:设成0.5或更小会刷屏且无实际意义;设成5以上大概率漏掉峰值 - 聚焦目标盘:比如只看
/dev/nvme0n1,就用iostat -dx 1 /dev/nvme0n1,避免被空闲盘拉低感知
rkB/s 冲高了,但不确定是不是真落盘?看这三个地方
rkB/s 高只是说明内核往块队列提交了大量读请求,不代表物理磁盘真的完成了那么多读。要验证是否真实发生,得交叉比对:
-
r_ios:如果rkB/s飙到 20000(≈20MB/s),但r_ios只有 10,说明是大块顺序读(avgrq-sz ≈ 2000 扇区);如果r_ios达到 5000,那就是小块随机读压队列 -
/sys/block/sda/stat第1列(reads completed):这是设备驱动确认完成的读次数,和r_ios接近但可能略低(因重试或丢弃),若两者长期偏差 >10%,说明底层有异常(如 NVMe 控制器降速、RAID 卡超时重发) -
r_await:若rkB/s高的同时r_await > 20ms(SSD)或> 100ms(HDD),基本可判定是真实读压力,不是缓存抖动
进程级读写峰值怎么定位?别用 iotop -o
iotop -o 显示的是带缓存的 DISK READ,它来自 /proc/[pid]/io 的 rchar,哪怕数据全从 page cache 返回也会计入——这会导致你看到某个进程“读了 500MB/s”,而 iostat -dx 1 显示整块盘 rkB/s 才 2MB/s。
- 真正反映进程真实磁盘读量的是
/proc/[pid]/io中的read_bytes字段,单位字节 - 实时盯峰值,用
pidstat -d 1:它的rkB/s列基于read_bytes差值计算,是瞬时值,不是累计 - 别用
pidstat -d 0:内核上报频率失控,终端卡死,还可能触发 OOM - 精准过滤:比如查 MySQL,用
pidstat -d 1 -p "$(pgrep -f 'mysqld')",比ps aux | grep mysqld更抗干扰
真正容易被忽略的是:rkB/s 峰值可能只持续 2~3 秒,但足以拖慢整个请求链路;而 r_ios 和 /sys/block/*/stat 的差异,往往暴露的是硬件层而非应用层问题——比如 NVMe 驱动 bug 导致请求重复下发,或者 RAID 卡固件静默丢包。











