首页/系统/Linux 内核与性能调优速查/块设备 IO 调度器切换

块设备 IO 调度器切换

单队列与多队列调度器名称不同:none(直通,NVMe 常用)、mq-deadline(默认折中)、bfq(交互友好)、kyber。

IO 调度器切换

块设备的 I/O 调度器决定请求如何排队、合并与下发。多队列时代常见取值:none(不排队直接下发,NVMe 等低延迟设备常用)、mq-deadline(带期限保证,避免请求饿死,默认折中)、bfq(按权重公平分配,交互友好但开销更高)、kyber(围绕延迟目标调节队列)。查看方式是读 /sys/block/<设备>/queue/scheduler,方括号标出当前值;切换直接写该文件。单队列时代的 noop 与 cfq 在新内核上已被取代或移除。

基本信息

查看cat /sys/block/<设备>/queue/scheduler
常见取值none、mq-deadline、bfq、kyber
切换方式直接写 scheduler 文件
持久化需 udev 规则,运行时设置重启失效
版本差异noop 改名为 none,cfq 已被移除

典型使用场景

  • SSD 与 NVMe 上换用 none 减少调度开销
  • 数据库等需要期限保证的场景使用 mq-deadline
  • 桌面或多任务交互场景使用 bfq 做公平分配
  • 排查 I/O 延迟抖动与调度器选择的关系
  • 把旧资料里的 cfq、noop 按当前内核版本换算

查看与切换

查看与切换
cat /sys/block/nvme0n1/queue/scheduler      # 方括号内是当前生效值
cat /sys/block/sda/queue/scheduler
echo none | sudo tee /sys/block/nvme0n1/queue/scheduler
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler
cat /sys/block/sda/queue/nr_requests         # 队列深度相关参数
cat /sys/block/sda/queue/rotational          # 1 表示机械盘,0 表示固态
lsblk -d -o NAME,ROTA,SCHED                  # 列出设备、类型与当前调度器

调度器特点

调度器特点适用场景
none不做排序合并,直接下发NVMe 等低延迟闪存设备
mq-deadline为请求设置期限,避免饿死通用服务器与数据库
bfq按权重公平分配,交互友好桌面与多任务交互场景
kyber围绕延迟目标调节队列对延迟较敏感的设备
改名历史容易混淆:单队列时代的 noop 已被 none 取代,cfq 在新内核中已移除,查资料先对齐内核版本。
运行时设置的调度器重启后失效,需要写 udev 规则或用内核参数固化,否则下一次重启会回到发行版默认值。

选择思路

  • 先确认设备类型:rotational 为 0 的固态设备优先考虑 none
  • 再看负载形态:随机小块多、延迟敏感时 deadline 或 bfq 更合适
  • 最后用 fio 在同一设备上对比切换前后的 IOPS 与延迟分位,用数据落地结论

易错点

  • 照抄旧资料里的 cfq:新内核已移除,写入报错或毫无效果
  • 以为换调度器就能提速:收益取决于设备类型与负载形态,需要实测
  • 忘记持久化:运行时设置重启失效,必须落到 udev 规则
  • 机械盘上使用 none:放弃请求合并与排序,随机访问表现可能更差
  • 只改调度器不管队列深度:两者共同决定并发度与延迟表现

数据来源与参考

  • Linux 内核 Documentation/block/
  • Linux 内核 Documentation/admin-guide/blockdev/
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌