cat /sys/block/sda/queue/scheduler 输出形如 [mq-deadline] kyber bfq none,方括号内为当前激活的调度器,仅表示选中状态而非性能效果;NVMe 设备常显示 [none],表明绕过传统调度、由硬件自主优化,非异常。

cat /sys/block/sda/queue/scheduler 能看到什么
这个命令只告诉你当前激活的调度器名称,比如 [mq-deadline],但完全不反映它对读写做了什么优化。方括号里的名字只是“选中状态”,不是性能报告。
常见误解是:看到 mq-deadline 就以为读写已优化——其实它只是加载了调度模块,是否真起作用、效果如何,得靠指标验证。
- 输出里没标出读/写队列分离、超时阈值、合并策略等实际行为参数
- 如果设备是 NVMe,可能显示
[none],这不代表没优化,而是内核绕过了传统调度层,由硬件自己处理 -
noop看起来最“简单”,但它在 SSD 上的收益来自省掉无意义的排序开销,不是靠算法本身优化读写
iostat -x 1 看什么才说明调度器起了作用
真正判断调度器是否优化读写的,是观察 await 和 avgqu-sz 的组合变化,而不是 %util 或 r/s 单独数值。
-
r_await > 1ms(SSD)或> 10ms(HDD)且avgqu-sz > 1→ 说明请求在队列里堆积,调度器可能没压住延迟,或队列深度设置不合理 -
avgqu-sz长期接近 0,但r_await很高 → 调度器没堵,问题在设备响应慢(坏盘、固件卡顿、远程存储延迟) - 改完调度器后
%util下降但await不变 → 可能只是调度器主动控速了,吞吐没提升,别误判为优化成功
为什么 echo deadline > /sys/block/sda/queue/scheduler 后没效果
写入成功不等于调度生效。很多情况下,调度器切换后看似成功,但业务 IO 延迟毫无改善,原因常被忽略:
- 目标设备名错了:重启后
sda可能变成sdb,尤其用了 LVM 或云盘;应优先用/dev/disk/by-path/路径绑定 udev 规则 - 设备不支持该调度器:NVMe 默认
[none],强行写deadline会静默失败,cat输出仍为[none] - 上层有干扰:LVM、mdraid、multipath 会拦截调度器设置,必须设在最底层物理设备(如
nvme0n1),而非逻辑卷(如dm-0) - 内核版本不匹配:RHEL8+/5.4+ 内核默认启用多队列,
deadline(无mq-前缀)仅适用于单队列路径,写入后可能被忽略
mq-deadline 的 write_expire 参数怎么调才影响读写行为
write_expire 控制写请求在队列里最长等待时间(微秒),直接影响日志类顺序写能否合并、小写是否被插队。但它不是“越大越好”或“越小越快”:
- 数据库 WAL 场景:设为
500000(500ms),利于合并连续写,降低 IOPS 压力 - 高并发小文件写:设为
50000(50ms),避免写请求长期霸占队列,让读请求及时穿插 - 改完立刻生效,但重启丢失;若用 systemd 服务持久化,注意路径权限和执行时机(需在 udev 加载设备后)
- 别和
read_expire混用:mq-deadline默认只暴露write_expire,read_expire已被移除,强行写会报Invalid argument
sda 是 HDD,nvme0n1 是 NVMe)必须分别设置,且 none 对 NVMe 不是故障信号,而是最优解。


















