iostat的%util接近100%却无卡顿,因其仅统计队列非空时间,不反映真实延迟;应优先关注await、r_await/w_await、avgqu-sz等iostat -x指标,尤其await超阈值(hdd>20ms/nvme>1ms)才表明存在i/o瓶颈。

为什么 iostat 显示的 %util 接近 100% 却没明显卡顿?
%util 表示设备忙于处理 I/O 请求的时间百分比,但它是基于“任一时刻只要队列非空就算忙”的粗粒度统计,并不等于真实响应延迟。尤其在多队列 NVMe 设备或启用了 io_uring 的场景下,%util 失去参考价值。
实操建议:
- 优先看
await(平均每次 I/O 等待+服务时间)和r_await/w_await,超过 10ms 要警惕 - 对比
avgqu-sz(平均队列长度)和svctm(已废弃,内核 2.6.34+ 不再更新,别信) - 用
iostat -x 1开启扩展统计,它才提供真正有用的指标 - SSD 场景下,
%util长期 80%+ 可能只是高吞吐常态,不等于瓶颈
iostat -x 必须关注的 4 个核心字段
不加 -x 的 iostat 输出基本无法定位真实 IO 问题。
关键字段含义与阈值参考:
-
r/s和w/s:每秒读/写请求数。HDD 超过 100、NVMe 超过 50k 时需结合rkB/s判断是否小 IO 密集 -
rkB/s和wkB/s:每秒读/写数据量(KB)。突然飙升可能对应备份、日志刷盘或数据库 checkpoint -
await:I/O 平均耗时(ms)。持续 > 20ms(HDD)或 > 1ms(NVMe)说明有排队或介质压力 -
%util:仅作辅助参考;若await正常但%util很高,大概率是并发请求多而非设备瓶颈
如何用 iostat 捕捉瞬时 IO 尖峰?
默认单次执行只显示自系统启动以来的平均值,完全看不出毛刺。必须用周期采样模式。
正确做法:
- 用
iostat -x 1 5:每秒刷新一次,共输出 5 组数据(第 1 组是历史平均,忽略;从第 2 组起才是实时窗口) - 若要记录到文件并事后分析:
iostat -x 1 > iostat.log 2>&1 &,运行够久后Ctrl+C停止 - 避免用
watch iostat -x:会清屏导致难以比对前后变化,且丢失滚动历史 - 高频率采样(如
-x 0.1)可能增加自身开销,生产环境慎用
为什么 iostat 看不到某块新挂载的 NVMe 盘?
常见于使用了多路径(multipath)、LVM 或 udev 规则重命名设备的场景——iostat 默认只显示底层物理设备(如 nvme0n1),而你操作的是映射后的名字(如 mpatha 或 dm-2)。
排查步骤:
- 运行
lsblk或ls /sys/block/确认设备是否被内核识别 - 检查是否被 multipath 掩盖:
sudo multipath -ll,若有,iostat应监控mpatha而非nvme0n1 - LVM 逻辑卷需看
dm-设备:iostat -x | grep dm-,对应关系查sudo dmsetup ls --tree - 某些云平台(如 AWS EBS)虚拟化层会隐藏真实设备,此时
iostat显示的是xvda或nvme0n1,但实际性能受宿主机限制,需结合云厂商监控
iostat 只是第一道筛子;看到异常指标后,下一步该用 iotop 定进程、pidstat -d 看线程级 IO、或 perf record -e block:block_rq_issue 追底层请求路径——这些容易被跳过的环节,才是真正卡点所在。










