应查设备驱动暴露的硬件队列深度:NVMe设备用cat /sys/block/nvme0n1/device/queue_depth,SATA/SAS设备用cat /sys/block/sda/device/queue_depth或nr_hw_queues,USB等单队列设备看cat /sys/block/sda/queue/nr_requests;若文件不存在,则队列深度由固件或内核硬编码决定。

怎么查设备驱动暴露的硬件队列深度
Linux 没有“系统级磁盘队列深度”这个统一配置项,lsblk -D 不显示它,iostat 的 avgqu-sz 是运行时平均值,不是上限。真要查限制能力,得看设备驱动层暴露的硬件队列深度文件:
- NVMe 设备(如
nvme0n1):cat /sys/block/nvme0n1/device/queue_depth—— 这是单个硬件队列的深度,现代 NVMe 多队列下,总并发能力是该值 × 队列数 - 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 的 avgqu-sz
iostat -x 输出的 avgqu-sz 是采样周期内 block layer 中“等待 + 正在处理”的请求数均值,它反映的是负载结果,不是设备能力边界:
- 值为 0.3 不代表“空闲”,可能只是请求稀疏;值为 32 也不代表“已满”,得对比设备的
queue_depth实际值(比如 NVMe 常是 64k,SATA SSD 多为 32) - 只有
avgqu-sz持续 >queue_depth × 0.8,才提示请求开始排队溢出;单独看数字高低没意义 - 当
await显著大于svctm(后者在新内核已废弃)时,avgqu-sz才有诊断价值;否则只是空闲波动
如何确认 queue_depth 是否真成瓶颈
别一看到 avgqu-sz 高就调大 queue_depth,先验证它是不是卡点:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 用
iostat -x 1观察:若%util ≈ 100%但r/s + w/s远低于设备标称 IOPS(例如 NVMe 标称 500k,实测仅 80k),且w_await > 10ms(SSD 应 - HDD 上盲目设高 depth 反而抬高平均延迟,保持默认 8–16 更稳;SSD 则优先检查
cat /sys/block/sdX/queue/scheduler,确保不是cfq等过时调度器拖慢 - 有 LVM、dm-crypt、mdadm 层时,
avgqu-sz会叠加多层排队,此时应比对/sys/block/dm-0/stat和底层物理盘的数值,才能定位真实瓶颈层
临时修改 queue_depth 的前提条件
写 /sys 接口看似简单,但必须同时满足几个硬性条件,缺一不可:
- 设备未被挂载(
umount /dev/sda1)且无进程打开(lsof /dev/sda必须为空) - 驱动支持 run-time 修改:NVMe 驱动通常支持;AHCI(SATA)部分旧驱动不支持,写入会报
Invalid argument - 目标值不能超过硬件上限:例如某些 SATA 控制器最大只允许 32,设 64 会静默失败或报
Operation not supported
最易被忽略的一点:虚拟机里若没直通存储,/sys/block/*/device/queue_depth 往往不可写,甚至路径都不存在——这时调优对象其实是宿主机的物理盘,而非 guest 内看到的 sr0 或 vda。










