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 与延迟分位,用数据落地结论