Fork me on GitHub
侧边栏

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依然是内核负责维护块设备层的人提出,其核心架构如图所示:

该架构的核心要点:

  1. 将软件层面提交的request queue 和提交到硬件的 queue分开,分别有多个Software queue和hardware queue, 内核为每个CPU(或者socket)维护一个software queue,解决锁竞争问题。
  2. hardware queue里的请求会直接发送给设备driver, 比如NVMe设备可能支持多个IO请求/完成 通道,所以hardware queue的数据和硬件相关。
  3. IO request的调度发生在software queue这里,主要做的事情和之前的io scheduler(比如cfs, deadline)类似,包括staging(合并和排序,对于ssd设备基本不需要排序),tagging, 以及fairness的权衡。
  4. 在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

优点:

  1. 系统响应更流畅:在高负载下仍能保持桌面环境的可用性。
  2. 适合多任务环境:多个进程同时读写磁盘时,能保持较好的公平性。
  3. 对慢速设备优化明显:如机械硬盘或低速 U 盘,能显著提升体验。
  4. 减少卡顿:尤其是在后台有大量 I/O 时,前台应用不会被“卡住”。

缺点:

  1. 吞吐量略低:相比 none 或 mq-deadline,BFQ 在纯性能测试中可能稍逊。
  2. 开销较大:调度逻辑复杂,CPU资源占用略高。
  3. 不适合高性能闪存设备:如 NVMe SSD 或高速 U 盘,none 调度器更高效。

MQ-Deadline

关于 mq-deadline 调度器,它是 Linux 多队列块层(Multi-Queue Block Layer)下的一个调度器,主要设计目标是 避免请求饿死,并在一定程度上保持低延迟和高吞吐量。下面是它与其他调度器(BFQ、Kyber、None)的比较,特别是针对 U 盘这类闪存设备:


🧠 mq-deadline 的特点

  • 是传统 deadline 调度器的多队列版本。
  • 使用读写分离的 FIFO 队列,确保请求不会长时间等待。
  • 适合 IO压力较大、功能单一的场景,如数据库或高并发写入任务。
  • 对于闪存设备(如 U 盘),其排序和合并机制可能带来额外开销

多队列调度算法

  1. mq-deadline
  2. bfq
  3. none
  4. kyber

单队列调度算法

  1. deadline
  2. cfq
  3. noop

查看目前可用的 IO 调度器

cat /sys/block/sda/queue/scheduler

与其他调度器的比较

调度器 优势 劣势 适合场景
None 最小开销,直接提交请求 无排序优化 高性能闪存设备(如 U 盘、NVMe)
Kyber 动态调整队列深度,读写分离 牺牲部分吞吐量以降低延迟 桌面系统、响应敏感应用
BFQ 高交互性,公平性好 吞吐量略低 多任务环境、桌面系统
mq-deadline 保证请求不会饿死,适度排序 对闪存设备优化不明显 高并发写入、数据库类应用
posted @ 2025-06-19 15:47  yooooooo  阅读(369)  评论(0)    收藏  举报