cat /sys/block/sda/queue/scheduler 是唯一可靠方式,lsblk -D 或 lsblk -T 均不显示 IO 调度算法;调度器是内核块层运行时策略,仅通过该 sysfs 路径暴露,输出中方括号内为当前生效项,NVMe 设备显示 [none] 属正常绕过软件调度。

cat /sys/block/sda/queue/scheduler 是唯一可靠方式
lsblk -D 或 lsblk -T 都不显示 IO 调度算法,它们只暴露丢弃能力(DISC-GRAN)或拓扑信息。调度器是内核块层运行时策略,只通过 /sys/block/设备名/queue/scheduler 暴露。
执行前先确认设备名:
-
lsblk -d列出物理块设备(排除loop、zram、dm-等逻辑设备) - 选中目标设备,比如
sda或nvme0n1 - 运行
cat /sys/block/sda/queue/scheduler
输出形如:[mq-deadline] kyber bfq none,方括号内即当前生效项。若看到 [none],多数情况是 NVMe 设备主动绕过软件调度层,不是配置错误。
为什么 cat /proc/partitions 或 df 里查不到调度器
IO 调度器不属于设备元数据,也不参与挂载或分区识别流程。它只在块设备初始化时由内核绑定,且每个设备独立维护——sda 和 sdb 可以运行不同调度器,nvme0n1 和 sdc 更可能完全不同。
常见误判点:
-
df -h显示的是文件系统使用率,和底层调度无关 -
cat /proc/partitions只列设备主次编号与大小,不含策略信息 -
dmesg | grep scheduler只显示内核编译支持的调度器列表,不是当前激活项
看到 [none] 就别硬切调度器
NVMe 设备在较新内核(5.0+)中默认启用 none,表示跳过 blk-mq 软件调度,交由硬件队列直接处理。此时:
- 向
/sys/block/nvme0n1/queue/scheduler写入kyber或bfq大概率失败,报Invalid argument - 即使写入成功,内核也可能忽略并维持
[none] - 云服务器(如阿里云ESSD、AWS io2)通常强制
none,/sys下该文件只读或根本不存在
真正需要干预的是 SATA SSD:若显示 [cfq](旧内核)或 [mq-deadline](新内核但性能不佳),才值得尝试切换。
临时切换后必须再 cat 一次确认
echo 写入只是发指令,不代表生效。尤其在 RAID 卡、老旧驱动或混用介质的机器上:
- 写入命令无报错 ≠ 生效(例如某些 LSI 卡拒绝
bfq) - 写入后立即
cat /sys/block/sda/queue/scheduler,看方括号是否移位 - 对根设备(如装系统的
sda)切换后,建议用iostat -x 1观察 30 秒,确认无异常延迟 spikes
如果反复写入仍卡在原值,说明该设备不支持目标调度器,或内核模块未加载(如 bfq 需要 CONFIG_BLK_MQ_BFQ_MODULE=y 编译支持)。


















