linux中io调度器按块设备独立配置,查当前值用cat /sys/block/设备名/queue/scheduler,方括号内为生效项;nvme设备显示[none]属正常,ssd推荐mq-deadline,hdd适用mq-deadline,临时修改用echo写sysfs,永久修改需添加elevator=参数至grub并更新配置。

Linux系统磁盘读写调度算法不是“配了就快”,而是得先看设备类型和负载特征,再选对调度器;盲目切换可能让延迟更高、吞吐更差。
怎么查当前磁盘用的什么调度器
调度器配置是按块设备独立设置的,sda、nvme0n1可能各用各的。查法固定:
- 运行
cat /sys/block/sda/queue/scheduler(把sda换成你的实际设备名) - 输出形如
noop deadline [mq-deadline] bfq,方括号里的是当前生效的 - 注意:不同内核版本支持的调度器不同,
mq-deadline在 5.0+ 才稳定,deadline是旧内核(4.x 及以前)的单队列版本
SSD/NVMe 该用 mq-deadline 还是 noop
多数人以为 SSD 就该用 noop,但这是过时经验。5.0+ 内核下,mq-deadline 对 NVMe 和 SATA SSD 实际表现更稳:
-
noop真正适用场景极少:纯硬件 RAID 卡、ramdisk、或云厂商明确声明底层已做 IO 调度(如 AWS EBS 优化实例) -
mq-deadline在 SSD 上不只做 FIFO,它仍会合并相邻请求、防饿死,并适配多队列架构,实测在数据库随机读写中比noop降低 10%~15% 的 99 分位延迟 - 如果你用的是 NVMe 盘(
nvme0n1),且内核 ≥ 5.0,优先试mq-deadline;若用的是老旧内核(如 CentOS 7 默认 3.10),则只能选deadline
临时改和永久改的区别与风险
临时改只是写进 sysfs,重启即丢;永久改要动启动参数或 udev 规则,但容易踩坑:
- 临时生效:
echo mq-deadline > /sys/block/sda/queue/scheduler(需 root 权限) - 永久生效推荐走 GRUB:编辑
/etc/default/grub,在GRUB_CMDLINE_LINUX_DEFAULT行末加elevator=mq-deadline,再运行update-grub或grub2-mkconfig -o /boot/grub2/grub.cfg - 别用
/etc/rc.d/rc.local方式——设备名(sda)在启动早期可能未就绪,脚本执行失败却无报错 - 别给所有盘统一硬编码调度器:系统盘用
mq-deadline,但 USB 外置 SSD 或虚拟机磁盘可能更适合none或kyber,混用会出问题
数据库场景下 deadline 参数调不调
默认 deadline 或 mq-deadline 的读超时 500ms、写超时 5s 已覆盖绝大多数数据库负载,一般不用动:
- 读超时太短(如设成 100ms)会导致频繁提前派发,增加驱动层压力,反而抬高平均延迟
- 写超时太长(如设成 30s)会让大日志刷盘阻塞其他请求,影响事务响应
- 真正需要调参的是
nr_requests(队列深度):MySQL 高并发写入时,可尝试echo 1024 > /sys/block/sda/queue/nr_requests,但必须配合iostat -x 1观察%util和await是否同步改善,否则就是无效调优
调度器不是“开关”,它是 IO 栈里承上启下的环节;改之前务必用 iostat -x 1 或 fio 做 baseline 测量,改之后至少跑 5 分钟真实负载再对比——否则你根本不知道自己是在优化,还是在埋雷。











