什么是 nr_requests
nr_requests 是块层为每块设备设置的排队请求上限:内核把来自不同进程的 IO 合并排序后放入该设备的请求队列,队列满后新的提交会被背压阻塞或走旁路。它属于上层队列深度,与设备本身的硬件队列深度(NVMe 的 queue_depth、SAS 的 tag 数)是两层概念:上层调大只让更多请求在场排队,并不能让设备本身变快,反而通常抬高单次 IO 的尾延迟。
基本信息
| 路径 | /sys/block/<dev>/queue/nr_requests |
|---|---|
| 典型默认 | SATA/SAS 常为 64 或 128,NVMe 常为 1024 |
| 调大影响 | 突发吞吐上升,平均与尾延迟通常上升 |
| 相关项 | queue/scheduler、queue/nr_requests、device/queue_depth |
| 持久化 | udev 规则或 tuned,重启后不保留 |
典型使用场景
- 顺序写为主的备份与归档:适当调大让 IO 队列填满,提升设备利用率
- 延迟敏感服务调参后出现 P99 恶化:先看是不是有人调大了队列深度
- 排查 IO 提交被阻塞:结合队列长度判断是设备慢还是上层次数过多
- 虚拟化宿主:给虚拟机磁盘评估队列深度,避免单个虚机抢占
- 存储阵列与 NVMe 上线时的基线核对:确认参数与厂商建议一致
查看与调整
查看与调整
cat /sys/block/sda/queue/nr_requests # 当前上限
cat /sys/block/sda/queue/scheduler # 顺带确认调度器
cat /sys/block/sda/device/queue_depth # 设备侧硬件深度
lsblk -o NAME,ROTA,SCHED,RA # 多设备一览
sudo sh -c 'echo 128 > /sys/block/sda/queue/nr_requests' # 调整
# 持久化示例(udev):ACTION=="add|change", KERNEL=="sda", ATTR{queue/nr_requests}="128"
iostat -x 1 5 | grep -w sda # 用 aqu-sz/await 验证前后差异相关指标与判读
| 指标 | 含义 | 异常信号 |
|---|---|---|
| aqu-sz | 平均队列长度(iostat -x) | 长期贴着 nr_requests 说明队列经常排队 |
| await | 平均 IO 完成时间(ms) | 调大队列后明显上升说明在牺牲延迟换吞吐 |
| queue_depth | 设备硬件并发能力 | 上层值远超它只会堆排队 |
| %util | 设备忙闲比例 | 接近 100% 提示设备已饱和,调参无效 |
多路径与 LVM 场景要区分调哪一层:dm-* 设备的队列与底层物理盘的队列各自独立,只改上层通常起不到预期效果。
队列深度与 IO 调度器(mq-deadline、none、bfq)共同决定行为,改之前先记录 iostat 基线,避免把配置变化当成设备改善。