I/O schedulers attempt to improve throughput by reordering request access into a linear order based on the logical addresses of the data and trying to group these together. While this may increase overall throughput it may lead to some I/O requests waiting for too long, causing latency issues. I/O schedulers attempt to balance the need for high throughput while trying to fairly share I/O requests amongst processes.
I/O调度器试图通过基于数据的逻辑地址将请求访问重新排序为线性顺序并尝试将这些地址分组来提高吞吐量。虽然这可能会增加总体吞吐量,但可能会导致一些I/O请求等待时间过长,从而导致延迟问题。I/O调度器试图平衡对高吞吐量的需求,同时试图在进程之间公平地共享I/O请求。
Different approaches have been taken for various I/O schedulers and each has their own set of strengths and weaknesses and the general rule is that there is no perfect default I/O scheduler for all the range of I/O demands a system may experience.
对于各种I/O调度器采取了不同的方法,每个调度器都有自己的优势和劣势,一般规则是,对于系统可能经历的所有I/O需求范围,没有完美的默认I/O调度器。
Multiqueue I/O schedulers
Note: These are the only I/O schedulers available in Ubuntu Eoan Ermine 19.10 and onwards.
The following I/O schedulers are designed for multiqueue devices. These map I/O requests to multiple queues and these are handled by kernel threads that are distributed across multiple CPUs.
注意:这些是Ubuntu Eoan Ermine 19.10及以后版本中唯一可用的I/O调度器。
以下I/O调度器是为多队列设备设计的。这些将I/O请求映射到多个队列,这些请求由分布在多个CPU上的内核线程处理。
bfq (Budget Fair Queuing) (Multiqueue)
Designed to provide good interactive response, especially for slower I/O devices. This is a complex I/O scheduler and has a relatively high per-operation overhead so it is not ideal for devices with slow CPUs or high throughput I/O devices. Fair sharing is based on the number of sectors requested and heuristics rather than a time slice. Desktop users may like to experiment with this I/O scheduler as it can be advantageous when loading large applications.
设计用于提供良好的交互式响应,特别是对于较慢的I/O设备。这是一个复杂的I/O调度器,每次操作的开销相对较高,因此对于CPU速度较慢或I/O设备吞吐量较高的设备来说并不理想。公平共享是基于请求的扇区数量和启发式方法,而不是时间片。桌面用户可能喜欢试用这种I/O调度程序,因为它在加载大型应用程序时非常有利。
kyber (Multiqueue)
Designed for fast multi-queue devices and is relatively simple. Has two request queues:专为快速多队列设备设计,相对简单。有两个请求队列:
Synchronous requests (e.g. blocked reads) 同步请求(例如阻塞读取)
Asynchronous requests (e.g. writes) 异步请求(例如写入)
There are strict limits on the number of request operations sent to the queues. In theory this limits the time waiting for requests to be dispatched, and hence should provide quick completion time for requests that are high priority. 发送到队列的请求操作的数量有严格的限制。理论上,这限制了等待调度请求的时间,因此应该为高优先级的请求提供快速完成时间。
none (Multiqueue)
The multi-queue no-op I/O scheduler. Does no reordering of requests, minimal overhead. Ideal for fast random I/O devices such as NVME. 多队列无操作I/O调度程序。不重新排序请求,开销最小。非常适合NVME等快速随机I/O设备。
mq-deadline (Multiqueue)
This is an adaption of the deadline I/O scheduler but designed for Multiqueue devices. A good all-rounder with fairly low CPU overhead. 这是对截止日期I/O调度器的改编,但专为多队列设备设计。一个很好的全能型,CPU开销很低。
Non-multiqueue I/O schedulers
NOTE: Non-multiqueue have been deprecated in Ubuntu Eoan Ermine 19.10 onwards as they are no longer supported in the Linux 5.3 kernel. 注意:在Ubuntu Eoan Ermine 19.10以后的版本中,非多队列已被弃用,因为它们在Linux 5.3内核中不再受支持。
deadline
This fixes starvation issues seen in other schedulers. It uses 3 queues for I/O requests: 这修复了其他调度器中出现的饥饿问题。它使用3个队列来处理I/O请求:
Sorted
Read FIFO - read requests stored chronologically 读取FIFO-按时间顺序存储的读取请求
Write FIFO - write requests stored chronologically 写入FIFO-按时间顺序存储的写入请求
Requests are issued from the sorted queue inless a read from the head of a read or write FIFO expires. Read requests are preferred over write requests. Read requests have a 500ms expiration time, write requests have a 5s expiration time. 在读或写FIFO头的读取未到期时,从排序队列发出请求。读请求优先于写请求。读取请求的有效期为500毫秒,写入请求的有效期限为5秒。
cfq (Completely Fair Queueing)
Per-process sorted queues for synchronous I/O requests. 同步I/O请求的按进程排序的队列。
Fewer queues for asynchronous I/O requests. 异步I/O请求的队列更少。
Priorities from ionice are taken into account. 来自ionice的优先级被考虑在内。
Each queue is allocated a time slice for fair queuing. There may be wasteful idle time if a time slice quantum has not expired. 为每个队列分配一个时间片,用于公平排队。如果时间片量子尚未过期,则可能存在浪费的空闲时间。
noop (No-operation)
Performs merging of I/O requests but no sorting. Good for random access devices (flash, ramdisk, etc) and for devices that sort I/O requests such as advanced storage controllers. 执行I/O请求的合并,但不进行排序。适用于随机访问设备(闪存、ramdisk等)和对I/O请求进行排序的设备,如高级存储控制器。
Selecting I/O Schedulers
Prior to Ubuntu 19.04 with Linux 5.0 or Ubuntu 18.04.3 with Linux 4.15, the multiqueue I/O scheduling was not enabled by default and just the deadline, cfq and noop I/O schedulers were available by default. 在使用Linux 5.0的Ubuntu 19.04或使用Linux 4.15的Ubuntu 18.04.3之前,多队列I/O调度在默认情况下未启用,默认情况下只有deadline、cfq和noop I/O调度程序可用。
For Ubuntu 19.10 with Linux 5.0 or Ubuntu 18.04.3 with Linux 5.0 onwards, multiqueue is enabled by default providing the bfq, kyber, mq-deadline and none I/O schedulers. For Ubuntu 19.10 with Linux 5.3 the deadline, cfq and noop I/O schedulers are deprecated. 对于Linux 5.0版的Ubuntu 19.10或Linux 5.0版以上的Ubuntu 18.04.3,默认情况下会启用多队列,提供bfq、kyber、mq-dealine和none I/O调度器。对于截止日期为Linux 5.3的Ubuntu 19.10,不推荐使用cfq和noop I/O调度器。
With the Linux 5.0 kernels, one can disable these and fall back to the non-multiqueue I/O schedulers using a kernel parameter, for example for SCSI devices one can use: 使用Linux 5.0内核,可以禁用这些并使用内核参数返回到非多队列I/O调度器,例如,对于可以使用的SCSI设备:
scsi_mod.use_blk_mq=0
...add this to the GRUB_CMDLINE_LINUX_DEFAULT string in /etc/default/grub and run sudo update-grub to enable this option. ...add this to the GRUB_CMDLINE_LINUX_DEFAULT string in /etc/default/grub and run sudo update-grub to enable this option. ...将其添加到/etc/default/grub中的GRUB_CMDLINE_LINUX_DEFAULT字符串中,然后运行sudo update GRUB以启用此选项。
Changing an I/O scheduler is performed on a per block device basis. For example, for non-multi queue device /dev/sda one can see the current I/O schedulers available using the following: 更改I/O调度程序是在每个块设备的基础上执行的。例如,对于非多队列设备/dev/sda,可以使用以下内容查看当前可用的I/O调度器:
cat /sys/block/sda/queue/scheduler
noop deadline [cfq]
to change this to deadline use: 要将其更改为deadline,请使用:
echo "deadline" | sudo tee /sys/block/sda/queue/scheduler
For multiqueue devices the default will show: 对于多队列设备,默认值将显示:
cat /sys/block/sda/queue/scheduler
[mq-deadline] none
To use kyber, install the module: 要使用kyber,请安装模块:
sudo modprobe kyber-iosched
cat /sys/block/sda/queue/scheduler
[mq-deadline] kyber none
and enable it: 并启用它:
echo "kyber" | sudo tee /sys/block/sda/queue/scheduler
To use bfq, install the module: 要使用bfq,请安装模块:
sudo modprobe bfq
cat /sys/block/sda/queue/scheduler
[mq-deadline] kyber none
and enable it: 并启用它:
echo "bfq" | sudo tee /sys/block/sda/queue/scheduler
Tuning I/O Schedulers
Each I/O scheduler has a default set of tunable options that may be adjusted to help improve performance or fair sharing for your particular use case. The following kernel documentation covers these per-I/O scheduler tunable options: 每个I/O调度程序都有一组默认的可调选项,可以对这些选项进行调整,以帮助提高性能或公平共享您的特定用例。以下内核文档介绍了这些per-I/O调度程序可调选项:
deadline (and mq-deadline) deadline-iosched.txt
cfq cfq-iosched.txt
bfq bfq-iosched.txt
kyber kyber-iosched.txt
Best I/O scheduler to use
Different I/O requirements may benefit from changing from the Ubuntu distro default. A quick start guide to select a suitable I/O scheduler is below. The results are based on running 25 different synthetic I/O patterns generated using fio on ext4, xfs and btrfs with the various I/O schedulers using the 5.3 kernel. 不同的I/O需求可能会从Ubuntu发行版默认值的更改中受益。下面是选择合适I/O调度程序的快速入门指南。结果是基于在ext4、xfs和btrfs上使用fio生成的25种不同的合成I/O模式,以及使用5.3内核的各种I/O调度器。
SSD or NVME drives
It is worth noting that there is little difference in throughput between the mq-deadline/none/bfq I/O schedulers when using fast multi-queue SSD configurations or fast NVME devices. In these cases it may be preferable to use the 'none' I/O scheduler to reduce CPU overhead. 值得注意的是,当使用快速多队列SSD配置或快速NVME设备时,mq deadline/none/bfq I/O调度器之间的吞吐量差异很小。在这些情况下,最好使用"none" I/O调度程序来减少CPU开销。
HDD
Avoid using the none/noop I/O schedulers for a HDD as sorting requests on block addresses reduce the seek time latencies and neither of these I/O schedulers support this feature. mq-deadline has been shown to be advantageous for the more demanding server related I/O, however, desktop users may like to experiment with bfq as has been shown to load some applications faster. 避免对HDD使用none/noop I/O调度器,因为对块地址的排序请求可以减少寻道时间延迟,而且这两个I/O调度器都不支持此功能。mq deadline已被证明对于要求更高的服务器相关I/O是有利的,然而,桌面用户可能喜欢尝试bfq,因为它已被证明可以更快地加载一些应用程序。
Of course, your use-case may differ, the above are just suggestions to start with based on some synthetic tests. You may find other choices with adjustments to the I/O scheduler tunables produce better results. 当然,您的用例可能会有所不同,以上只是基于一些合成测试的建议。您可能会发现,通过调整I/O调度程序的可调参数,其他选择会产生更好的结果。