iostat -dx 1 直接输出毫秒级真实读写延迟:r_await 和 w_await 即设备层平均耗时,hdd超10ms、sata ssd超1ms、nvme超0.5ms需立即排查。

iostat -dx 1 能直接告诉你读写延迟是多少
别绕弯子,iostat -dx 1 是唯一能从内核原始数据里实时抠出「读延迟」和「写延迟」的命令。它输出的 r_await 和 w_await 就是毫秒级的平均值,不是估算,不是代理指标,就是设备层真实耗时。
常见错误是只跑 iostat 不加参数,或者漏掉 -x —— 那样根本看不到 r_await/w_await,只有一堆吞吐量数字,完全无法判断延迟是否异常。
-
-d:屏蔽 CPU 行,避免干扰磁盘判断 -
-x:必须加,否则r_await/w_await字段不出现 -
1:每秒刷新,方便观察波动;用iostat -dx 1 3可抓 3 次快照做对比 - HDD 延迟超
10ms、SATA SSD 超1ms、NVMe 超0.5ms就该查了
iotop 只能辅助验证,不能替代 iostat 看延迟
iotop 显示的是进程级 I/O 活动,它本身不提供任何延迟数值,但能帮你确认「高延迟是不是真由某个进程触发」。
关键点在于权限和参数:不加 sudo,iotop 只能看到当前用户进程,且无法读取 /proc/*/io,很多关键列(比如 IO%、DISK WRITE)会为空或不准。
- 必须用
sudo iotop -o:只显示当前有 I/O 的进程,排除休眠干扰 - 别信
IO%列:它是相对占比,不是绝对延迟;盯DISK READ/DISK WRITE的 KB/s 更实在 - 看到
mysqld或java占比高?立刻lsof -p $(pgrep mysqld)查它在写哪个文件,再cat /proc/$(pgrep mysqld)/io对比read_bytes和rchar—— 差太多说明卡在 page cache,不是磁盘慢
fio 和 ioping 不是日常查看工具,而是定位长尾或硬件问题的触发器
当 iostat 显示 r_await 平均值正常(比如 0.3ms),但业务偶尔卡顿严重,这时才轮到 fio 和 ioping 出场。它们不回答「现在延迟多少」,而回答「最差情况有多差」「底层设备是否可靠」。
-
fio测长尾:配置里必须设direct=1(绕缓存)、runtime=60(够采样)、iodepth=32(模拟并发),否则测出来的是缓存速度,不是真实延迟分布 -
ioping测裸设备:用ioping -C -c 10 /dev/nvme0n1,-C强制同步落盘,排除文件系统和缓存干扰;avg超0.2ms就得怀疑 NVMe 控制器或固件 - 别用
dd测延迟:dd if=/dev/zero of=test bs=1M count=1024 oflag=direct只反映顺序大块吞吐上限,完全不模拟随机小 IO 场景
真正容易被忽略的坑:区分「排队延迟」和「服务延迟」
r_await = 排队时间 + 服务时间,但内核已废弃 svctm 字段,所以你没法直接拆开看。实际中,如果 aqu-sz 持续 > 1,而 r_await 高,大概率是请求在队列里等,不是磁盘响应慢——这时候优化方向是调低并发、改调度器、检查上层锁,而不是换硬盘。
另一个盲区是 NVMe 设备的 %util 失效:多队列架构下,%util 仍可能很低,但 aqu-sz 已飙到 10+,说明队列深度压爆了。这种情况下,盯着 %util 会误判为「磁盘很闲」。











