iostat -x 1 是分析高并发下队列深度与处理时延的唯一有效起点,需重点关注 w_await、avgqu-sz、%util 三字段组合趋势,结合硬件队列深度与 await/svctm 拆解判断瓶颈归属。

直接用 iostat -x 1 每秒刷新扩展指标,是分析高并发下队列深度与处理时延的唯一有效起点。关键不是看平均值,而是捕捉瞬时堆积和延迟毛刺——真实瓶颈往往藏在 95% 分位之后。
盯紧三个核心字段:w_await、avgqu-sz、%util
在极高并发场景中:
- w_await(写请求平均耗时)超过 20ms 且明显高于设备理论服务时间(如 NVMe 应 ≤ 1ms),说明写请求大量滞留在队列中,而非设备响应慢;
- avgqu-sz(平均队列长度)持续 > 10 且同步伴随 w_await 上升,表明上层提交过快,块层或设备已无法及时消化;
- %util ≈ 100% 不代表磁盘“忙满”,尤其对 NVMe 而言,它可能仅反映调度器层面饱和,实际吞吐远未达物理上限——此时更应信任 w_await 和 avgqu-sz 的组合趋势。
结合硬件队列深度验证是否真瓶颈
Linux 实际生效的队列深度由应用层、内核 blk-mq 层、硬件层三者最小值决定。需交叉验证:
- 查当前硬件队列容量:cat /sys/block/nvme0n1/device/queue_depth(NVMe)或 cat /sys/block/sda/device/queue_depth(SATA/SCSI);
- 查逻辑队列深度:cat /sys/block/nvme0n1/queue/depth;
- 若 avgqu-sz 长期接近甚至等于该值(如 queue_depth=256,avgqu-sz≈240),基本可判定是深度不足导致请求“堵门口”;
- 注意:盲目调大 queue_depth 可能引发设备内部拥塞或锁竞争,OLTP 类负载建议设为 64–256,顺序吞吐类保持 32–64 即可。
区分排队延迟与设备服务延迟
await = 队列等待时间 + 设备服务时间。高并发下二者必须拆开看:
- 如果 w_await 高但 svctm 极低(如 w_await=85ms,svctm=0.18ms),说明写请求几乎全耗在排队上,问题在上层(如文件系统日志刷盘、ext4 barrier 等待、XFS log stall);
- 如果 r_await 与 w_await 差距大(如 r_await=3ms,w_await=68ms),说明读写路径不均衡,可能是 WAL 日志盘无压力,但数据盘因元数据更新或锁竞争卡住;
- svctm 在 Linux 2.6+ 内核中已是估算值,不可信,一律以 w_await 和 r_await 为准,再配合 avgqu-sz 判断归属。
避免被干扰数据误导
高并发监控极易被噪声掩盖本质:
- 务必指定设备名:iostat -x 1 /dev/nvme0n1,避免默认汇总把空闲盘拉低指标;
- 跳过首行输出(它是自启动以来均值),从第二行开始观察动态趋势;
- 若 rrqm/s 或 wrqm/s 显著升高,说明上层(page cache、IO 调度器)做了大量请求合并,可能掩盖了小 IO 的真实随机延迟,此时需配合 ioping -C /dev/nvme0n1 测裸设备毫秒级延迟作基线比对;
- 对比 /proc/diskstats 中字段 9(# of IOs merged)是否突增,也是队列入口拥堵的佐证。











