linux没有“当前实时队列长度”指标,avgqu-sz是唯一反映平均队列长度的值,但必须结合await和硬件能力综合判断,否则无意义。

Linux 没有“当前实时队列长度”这个可读数值,avgqu-sz 是唯一能直接反映平均队列长度的指标,但它必须结合 await 和硬件能力一起看,否则毫无意义。
为什么不能用 iostat -x 看“当前”队列长度
iostat -x 1 输出的 avgqu-sz 是采样周期(如 1 秒)内块层中等待+进行中请求的**算术平均值**,不是瞬时快照:
- 它不区分请求大小、不体现排队位置(是块层?驱动层?设备内部?)
- 值为 0.3 不代表“队列空”,可能只是稀疏 IO;值为 45 也不代表“已满”,得先知道设备理论深度
- 机械盘上
avgqu-sz长期 > 4 且await> 10ms → 才说明真在排队 - NVMe 上
avgqu-sz= 80 却await
怎么查设备真正的硬件队列深度上限
这才是你该关心的“队列长度能力”,而非运行时平均值。路径因设备类型而异:
- NVMe 设备(如
nvme0n1):cat /sys/block/nvme0n1/device/queue_depth - SATA/SAS 设备(如
sda):cat /sys/block/sda/device/queue_depth或cat /sys/block/sda/device/nr_hw_queues(再结合单队列深度推算) - 老式单队列设备(如部分 USB 盘):
cat /sys/block/sda/queue/nr_requests - 若
queue_depth文件不存在,说明由固件或内核硬编码决定,不可运行时修改
如何判断队列是否真成瓶颈,而不是误读 avgqu-sz
别只盯着数字高低,看组合信号:
- 用
iostat -x 1观察:%util≈ 100% 且r_ios + w_ios远低于设备标称 IOPS(如 NVMe 标称 500k,实测仅 80k)且await> 10ms → 才值得怀疑深度不够 - 若
avgqu-sz很低(如 0.3)但await却飙升(如 50ms)→ 问题不在队列,而在设备响应变慢或驱动挂起,查svctm(已废弃,仅作参考)和dmesg - 有 LVM、dm-crypt、mdadm 层时,
avgqu-sz会叠加多层排队,此时应对比/sys/block/dm-0/stat和底层物理盘的aveq字段
想抓真实排队行为,别只信 iostat
iostat 是聚合统计,掩盖了请求分布。当 avgqu-sz 异常但找不到大户进程时,必须下沉一层:
- 用
pidstat -d 1看每个进程的 IO 等待时间(%iowait列),比iotop更稳 - 用
blktrace -d /dev/sda -o - | blkparse -i -抓原始事件流,重点看Q→G(进队列到取请求)延迟:若大,说明块层调度或锁争用;I→C(下发到完成)超长,则直奔硬件或驱动 - 查
/proc/diskstats的io_ticks字段:如果它 1 秒内涨了 800ms,说明设备真在满负荷
真正容易被忽略的是:队列深度不是越大越好。HDD 上盲目设高反而抬高平均延迟;NVMe 上盲目调到 4096 可能引发驱动锁竞争,让 await 波动更大。关键永远是——await 是否开始抬升,%util 是否持续卡死,以及实际 IOPS 是否远低于理论值。











