磁盘卡顿常因I/O调度器选错导致,需先用cat /sys/block/sda/queue/scheduler确认当前调度器及设备类型,再按NVMe(选noop)、HDD(选deadline/mq-deadline)、高并发服务器(新内核选bfq、旧内核选mq-deadline)匹配切换,并通过iostat -x 1验证await是否显著下降。

磁盘卡顿常表现为 iowait 高、await 值飙升、%util 持续 95%+,而 I/O 调度器选错是常见隐形原因。它不直接“修复硬件”,但能显著减少请求排队、避免饥饿或调度开销反噬性能。
先确认当前调度器和设备类型
执行:
cat /sys/block/sda/queue/scheduler
输出类似 [mq-deadline] kyber bfq noop,括号内为当前生效项。
关键要判断底层设备:
- NVMe SSD(如 Samsung PM1733、Intel Optane)→ 内部控制器已做深度排序,无需软件调度
- SATA/SAS SSD 或 RAID 卡后端 → 视控制器能力,通常也倾向轻量调度器
- 传统 HDD(机械盘)→ 需要寻道优化,deadline 或 mq-deadline 更稳妥
按场景切换合适调度器
临时生效(重启失效),以 sda 为例:
- NVMe 设备卡顿:用 echo noop > /sys/block/nvme0n1/queue/scheduler(注意设备名是 nvme*)
- 数据库或低延迟服务(如 Redis、Kafka):用 echo deadline > /sys/block/sda/queue/scheduler
- 高并发混合读写服务器(如 Web+DB 共存):bfq 在较新内核(≥5.0)中表现更稳,可试 echo bfq > /sys/block/sda/queue/scheduler
- 旧内核(如 CentOS 7.9 的 3.10)无 kyber/bfq?优先选 mq-deadline(比 legacy deadline 更适配多队列设备)
让修改永久生效
仅改 /sys 下参数会丢失。持久化方法有两种:
- GRUB 方式(全局生效):编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 行末加 elevator=noop(或 deadline/bfq),再运行 grub2-mkconfig -o /boot/grub2/grub.cfg 并重启
-
udev 规则(按设备精准控制):新建 /etc/udev/rules.d/60-ioscheduler.rules,写入:
ACTION=="add|change", KERNEL=="nvme[0-9]n[0-9]", ATTR{queue/scheduler}="noop"
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="deadline"
然后运行 udevadm control --reload-rules && udevadm trigger
切换后必须验证效果
别只看调度器变了就认为好了。用以下组合验证是否真缓解卡顿:
- 持续运行 iostat -x 1,观察 await 是否从 >50ms 降至 %util 是否不再长期打满
- 用 iotop -o 看高 IO 进程的 IO% 是否下降、D 状态进程是否减少
- 若卡顿仍存在,说明问题可能不在调度层——比如是日志同步阻塞(journald fsync)、文件系统锁争用、或应用频繁小写 + fsync,需进一步排查











