linux中无统一系统级磁盘队列深度,lsblk -d不显示它,iostat的avgqu-sz是运行时平均长度而非配置上限;真正需查的是硬件队列深度(如cat /sys/block/nvme0n1/device/queue_depth)和软件限制(如nr_requests),并结合设备类型、调度器及多队列结构综合判断。

Linux 中没有统一的“系统级磁盘队列深度”概念,lsblk -D 不显示它,iostat 里的 avgqu-sz 是运行时平均长度而非配置上限——真正要查的是设备驱动层暴露的硬件队列深度和软件调度限制。
怎么看当前设备的硬件队列深度
队列深度分硬件(per-hw-queue)和软件(如 nr_requests)两层,SSD/NVMe 和 SATA 设备路径不同:
- NVMe 设备(如
nvme0n1):用cat /sys/block/nvme0n1/device/queue_depth,新驱动可能需查/sys/block/nvme0n1/device/nvme*/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 文件存在且可读,才代表驱动支持运行时调整;若报 No such file,说明由固件或内核硬编码决定,不可改。
为什么 iostat -x 的 avgqu-sz 不能当队列深度用
avgqu-sz 是采样周期内内核 block layer 中等待+进行中的请求数均值,它反映负载结果,不是能力上限:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 值为 0.8 不代表“还有空间”,可能只是当前 IO 模式稀疏;值为 25 不代表“已满”,得看设备理论最大值(NVMe 常是 64k,SATA SSD 多为 32)
- 持续 > 设备
queue_depth× 0.8,才说明请求在排队溢出;仅看数字高低无意义 -
await显著 >svctm时,avgqu-sz才有诊断价值——否则只是空闲波动
怎么判断队列深度是否真成瓶颈
不能只调大 queue_depth,得先确认它确实是卡点:
- 用
iostat -x 1观察:若%util ≈ 100%但r_ios + w_ios远低于设备标称 IOPS(如 NVMe 标称 500k IOPS,实测仅 80k),且await> 10ms,才怀疑深度不够 - HDD 上盲目设高 depth 反而抬高平均延迟,保持默认 8–16 更稳;SSD 则优先查
cat /sys/block/sdX/queue/scheduler,确保不是cfq等过时调度器拖慢 - 有 LVM、dm-crypt、mdadm 层时,
avgqu-sz会叠加多层排队,此时看/sys/block/dm-0/stat和底层物理盘对比更准
临时调队列深度要避开的坑
写 /sys 接口看似简单,但几个条件缺一不可:
- 设备未被挂载或打开(
umount /dev/sda1,且无进程lsof /dev/sda) - 驱动支持 run-time 修改(NVMe 驱动通常支持,AHCI SATA 多数不支持)
- 数值必须是 2 的整数幂(如 16、32、64),非任意整数
- 设完立即生效,但重启丢失;永久生效需加内核参数(如
nvme_core.default_queue_depth=256),且要update-grub && reboot
最易忽略的一点:NVMe 多队列下,queue_depth 是单个硬件队列的深度,总并发能力 = nr_hw_queues × queue_depth,别只改一个数就以为翻倍了。










