当前io调度器为方括号内标识者,hdd用mq-deadline最稳,sata ssd推荐mq-deadline或kyber,nvme ssd应设为none;验证需盯await和avgqu-sz而非%util。

直接看当前设备用的是哪个调度器,再按存储类型换——别猜,别套模板,SSD 用 bfq 多半是自找麻烦。
怎么查当前 IO 调度器和可用选项
执行 cat /sys/block/sda/queue/scheduler(把 sda 换成你的设备名),输出类似 [mq-deadline] kyber bfq none。方括号里那个就是当前生效的。
- 不同内核版本支持的调度器不同,RHEL8/CentOS8+ 默认是多队列调度器,
cfq已淘汰,noop被none替代 -
sr0(光驱)、nvme0n1这类设备可能默认就是[none],别急着改 - 如果看到
deadline(无mq-前缀),说明是老内核或虚拟环境,需确认是否真在用单队列路径
按存储类型选调度器:HDD、SATA SSD、NVMe 各有最优解
选错比不调更伤性能,尤其是 SSD 类设备。
-
HDD:磁头寻道代价高,优先压随机 IO。用
mq-deadline最稳;若小文件读多且延迟敏感(如 NFS 服务),可试bfq,但必须调大slice_idle_us(否则它会频繁插队) -
SATA SSD:无寻道,但控制器队列浅、写放大明显。推荐
mq-deadline或kyber;bfq在这里基本没收益,还多占 CPU -
NVMe SSD:原生支持 64K+ 硬件队列,内核调度意义极小。直接设为
none是通用做法;只有需用 cgroup v2 的io.weight做容器级限流时,才考虑切回kyber
改完怎么验证不是“看起来好了”
iostat -x 1 的 %util 接近 100% ≠ 真瓶颈,它可能是调度器主动控速的结果。
- 盯
await:r_await> 10ms(HDD)或 > 1ms(SSD)才说明延迟异常 - 盯
avgqu-sz:长期 > 1 表示请求在队列里堆着,结合await高,才说明是调度器堵了;如果avgqu-sz低但await高,大概率是设备本身慢或故障 -
svctm已被内核弃用,别信;%wa高但%util低?那 IO 可能卡在网络、远程存储或其它设备上
参数微调只在明确瓶颈后做,且重启失效
比如用 mq-deadline 时:
-
echo 500000 > /sys/block/sda/queue/iosched/write_expire:延长写超时,利于日志类顺序写合并 -
echo 1 > /sys/block/sda/queue/iosched/fifo_batch:减小批量处理数,小 IO 密集场景响应更快 - 所有写入
/sys的修改都是临时的,要持久化得加到 udev 规则或启动脚本里(例如/etc/rc.local或 systemd service)
多数人卡在“以为改了就生效”,其实连设备名都可能因重启变(sda → sdb),用 by-path 或 by-uuid 的 udev 规则才靠谱。










