Linux 内核IO 调度器之 none vs kyber vs BFQ vs mq-deadline
Multiqueue Block Layer
随着存储设备(特别是NVME+SSD块设备)的性能提升,之前Linux内核里的块存储层的设计已经无法满足需求,主要是单个的request queue成为瓶颈,在多cpu情况下产生大量的锁竞争,效率低下。另一方面,ssd盘在硬件层面早已可以支持百万级的IOPS,这样内核里需要新的blocker层成为必然。
Multiqueue blocker layer依然是内核负责维护块设备层的人提出,其核心架构如图所示:
该架构的核心要点:
- 将软件层面提交的request queue 和提交到硬件的 queue分开,分别有多个Software queue和hardware queue, 内核为每个CPU(或者socket)维护一个software queue,解决锁竞争问题。
- hardware queue里的请求会直接发送给设备driver, 比如NVMe设备可能支持多个IO请求/完成 通道,所以hardware queue的数据和硬件相关。
- IO request的调度发生在software queue这里,主要做的事情和之前的io scheduler(比如cfs, deadline)类似,包括staging(合并和排序,对于ssd设备基本不需要排序),tagging, 以及fairness的权衡。
- 在block device设备驱动层面,需要适配一些变化,比如driver要暴露硬件的submission queue的数量和长度,支持Tagged IO。
当前支持multi-queue的drivers包括:virtio-blk, NVMe, scsi, loop等等。
Kyber调度器
在Multiqueue blocker layer在 内核3.13版本合入之后,相应的software queue(也叫soft-context) level的调度器也相应的诞生,其中一个叫做Kyber调度器,该调度器主要是保证io request的latency, 那么显然在某些情况下会牺牲throughput. 做法是通过调整异步IO的队列深度,提高同步IO的队列深度来保证同步IO不被异步IO严重阻塞,这里同步IO往往对应read,异步IO对应write。
Kyber中引入了所谓调度域(domain)的概念,所谓的scheduling domain其实就是指不通类型的IO操作,比如read, write, discard等等。
Kyber可以根据io latency的统计信息动态调整每个调度域在software queue里的深度,如果某个domain的时延满足要求,则减少队列的深度,如果时延比较大,表示没有足够的这类请求被提交到hardware queue,则增大该domain队列深度。
nvme设备使用kyber调度器:
echo kyber > /sys/block/nvme*/queue/scheduler
主要的latency参数调整方法:
/sys/block/nvme* /queue/iosched/read_lat_nsec
/sys/block/nvme* /queue/iosched/write_lat_nsec
/sys/block/nvme* /queue/iosched/discard_lat_nsec
单位是ns,分别对应read/write/disard操作。
BFQ
优点:
- 系统响应更流畅:在高负载下仍能保持桌面环境的可用性。
- 适合多任务环境:多个进程同时读写磁盘时,能保持较好的公平性。
- 对慢速设备优化明显:如机械硬盘或低速 U 盘,能显著提升体验。
- 减少卡顿:尤其是在后台有大量 I/O 时,前台应用不会被“卡住”。
缺点:
- 吞吐量略低:相比 none 或 mq-deadline,BFQ 在纯性能测试中可能稍逊。
- 开销较大:调度逻辑复杂,CPU资源占用略高。
- 不适合高性能闪存设备:如 NVMe SSD 或高速 U 盘,none 调度器更高效。
MQ-Deadline
关于 mq-deadline 调度器,它是 Linux 多队列块层(Multi-Queue Block Layer)下的一个调度器,主要设计目标是 避免请求饿死,并在一定程度上保持低延迟和高吞吐量。下面是它与其他调度器(BFQ、Kyber、None)的比较,特别是针对 U 盘这类闪存设备:
🧠 mq-deadline 的特点
- 是传统 deadline 调度器的多队列版本。
- 使用读写分离的 FIFO 队列,确保请求不会长时间等待。
- 适合 IO压力较大、功能单一的场景,如数据库或高并发写入任务。
- 对于闪存设备(如 U 盘),其排序和合并机制可能带来额外开销
多队列调度算法
- mq-deadline
- bfq
- none
- kyber
单队列调度算法
- deadline
- cfq
- noop
查看目前可用的 IO 调度器
cat /sys/block/sda/queue/scheduler
与其他调度器的比较
| 调度器 | 优势 | 劣势 | 适合场景 |
|---|---|---|---|
| None | 最小开销,直接提交请求 | 无排序优化 | 高性能闪存设备(如 U 盘、NVMe) |
| Kyber | 动态调整队列深度,读写分离 | 牺牲部分吞吐量以降低延迟 | 桌面系统、响应敏感应用 |
| BFQ | 高交互性,公平性好 | 吞吐量略低 | 多任务环境、桌面系统 |
| mq-deadline | 保证请求不会饿死,适度排序 | 对闪存设备优化不明显 | 高并发写入、数据库类应用 |


浙公网安备 33010602011771号