cat /sys/block/sda/queue/scheduler 才是查看 Linux IO 调度器最准确、最可靠的方法;像 lsblk -D、iostat、df 这些常见命令,都无法直接看出当前使用的是哪一种 IO 调度算法。命令输出中,带方括号的那一项就是当前已经生效的调度器,例如 [mq-deadline];而 NVMe 设备通常会显示 [none],这表示它直接绕过了软件调度层。

cat /sys/block/sda/queue/scheduler 是唯一可靠的查看方式
lsblk -D、iostat、df 都不会显示当前 IO 调度器,它们主要提供磁盘拓扑、性能统计或文件系统使用情况。IO 调度器属于 Linux 内核块层的运行时策略,只会通过 /sys/block/设备名/queue/scheduler 这个 sysfs 接口对外暴露。
在查询之前,必须先确认真实的块设备名称,再检查对应路径:
- 使用
lsblk -d或cat /proc/partitions列出物理块设备,排除loop、dm-、zram等虚拟设备 - 对于 SATA 设备(如
sda),执行cat /sys/block/sda/queue/scheduler - 对于 NVMe 设备(如
nvme0n1),执行cat /sys/block/nvme0n1/queue/scheduler
输出通常类似 [mq-deadline] kyber bfq none,其中方括号 [] 内的项目就是当前正在使用的 IO 调度器。看到 [none] 并不代表异常——这在 NVMe 设备上很常见,意味着内核跳过软件调度层,由硬件直接处理请求。
为什么 cat 出来一串名字,却不知道哪个正在使用?
关键就在方括号的位置。例如输出 noop [deadline] mq-deadline,说明当前激活的是 deadline;如果显示 [none] mq-deadline kyber,则表示当前使用的是 none,其他名称只是当前可选的调度器,并不是正在生效的配置。
常见误判点包括:
lsblk -D显示的DISC-GRAN等参数与 IO 调度器没有关系dmesg | grep scheduler只能看到内核支持或加载过哪些调度器,不能代表运行时实际启用的是哪一个- 某些老旧驱动或 RAID 控制卡会屏蔽部分调度器,
cat输出中没有列出的选项,实际上就不可用
查不到 scheduler 文件?可能是设备不支持,或路径写错了
如果执行 cat /sys/block/sda/queue/scheduler 提示 No such file or directory,通常是以下几种情况之一:
- 设备名写错,例如把
nvme0n1p1(分区)误当成nvme0n1(主设备)——必须使用主设备名,不能带p1 - 该设备本身没有软件调度层,例如部分 virtio-blk 或某些 USB 存储设备,
/sys/block/xxx/queue/目录下根本不存在scheduler文件 - 内核启动时禁用了 blk-mq(这种情况非常少见,但理论上存在)
可以先验证路径是否存在:ls /sys/block/sda/queue/ | grep scheduler。如果没有结果,就不要反复尝试,应改查其他设备或结合硬件文档进一步确认。
临时切换后 cat 没变化?这通常是写入失败的典型表现
执行 echo kyber > /sys/block/sda/queue/scheduler 后再次使用 cat 检查,若发现方括号位置没有变化,通常说明写入没有成功。常见原因如下:
- 权限不足:必须使用 root 权限,推荐执行
sudo sh -c 'echo kyber > /sys/block/sda/queue/scheduler' - 写入了非法值:只能写入
cat输出中列出的调度器名称,例如输出只有[mq-deadline] kyber,就不能写bfq - NVMe 强制使用
none:如果设备显示[none],并且写入其他值时返回Invalid argument,这是内核主动拒绝,不是命令操作错误 - RAID 卡固件限制:某些 LSI 或 MegaRAID 控制卡只支持
noop或deadline,其他值即使写入也可能被忽略
真正切换成功的判断标准,是 cat 输出中方括号位置发生变化,并且写入过程中没有报错。不要只看“命令似乎执行成功”,必须再次验证当前生效的 IO 调度器。
还有一个很容易被忽视的重点:每个块设备的 IO 调度器都是独立配置的,sda 和 nvme0n1 可以使用完全不同的调度策略。因此,无论是查看还是修改,都必须按设备逐一操作,并不存在“整个系统统一设置一个调度器”的情况。
