选择Linux I / O调度程序


82

我读到,据说可以通过写入/ sys / block / [disk] / queue / scheduler来更改正在运行的内核上特定设备的I / O调度程序。例如,我可以在系统上看到:

anon@anon:~$ cat /sys/block/sda/queue/scheduler 
noop anticipatory deadline [cfq] 

默认值是完全公平的队列调度程序。我想知道的是,在自定义内核中包括所有四个调度程序是否有任何用处。除非内核足够聪明地为正确的硬件选择正确的调度程序,特别是基于闪存的驱动器的“ noop”调度程序,以及针对传统驱动器的其他调度程序,否则编译一个以上的调度程序似乎没有多大意义。硬盘。

是这样吗

Answers:


109

如中所述/usr/src/linux/Documentation/block/switching-sched.txt,可以在运行时更改任何特定块设备上的I / O调度程序。可能会有一些延迟,因为在使用新的调度程序之前,所有先前的调度程序的请求都已清除,但是即使设备使用过多,也可以毫无问题地对其进行更改。

# cat /sys/block/hda/queue/scheduler
noop deadline [cfq]
# echo anticipatory > /sys/block/hda/queue/scheduler
# cat /sys/block/hda/queue/scheduler
noop [deadline] cfq

理想情况下,将有一个调度程序来满足所有需求。它似乎还不存在。内核通常没有足够的知识来为您的工作负载选择最佳的调度程序:

  • noop 通常是内存支持的块设备(例如ramdisk)和其他非旋转介质(闪存)的最佳选择,在这些设备中尝试重新计划I / O会浪费资源
  • deadline 是一个轻量级的调度程序,它试图对延迟进行严格限制
  • cfq 尝试维护I / O带宽在系统范围内的公平性

默认设置anticipatory很长时间,它进行了很多调整,但是在2.6.33(2010年初)中已被删除。 cfq成为前一段时间的默认设置,因为它的性能合理且公平是多用户系统(甚至单用户桌面)的一个好目标。在某些情况下-数据库经常被用作示例,因为它们往往已经具有自己独特的调度和访问模式,并且通常是重要的服务(所以谁在乎公平性?)-anticipatory具有可调性的悠久历史以在这些工作负载上获得最佳性能,并deadline很快将所有请求传递到基础设备。


1
很好的信息,谢谢!但是我的基本问题仍然没有得到解答,如果我插入闪存驱动器或上网本用闪存驱动器运行,因为它的主驱动器是否内核足够聪明,可以选择noop而不是默认的cfq?还是完全由我决定手动执行此操作?
罗伯特·S·巴恩斯

3
您可以将内核配置为默认使用其他调度程序。自动noop在非旋转媒体上使用会很聪明,但是内核没有该功能。确实可以检测到非旋转媒体,但是由于某些磁盘误报自身而导致的可靠性不高,而且还没有连接到I / O调度程序代码。
短暂

8
您可以添加udev规则来根据设备特征定义调度程序,如debian wiki(wiki.debian.org/SSDOptimization#Low-Latency_IO-Scheduler)#为非旋转磁盘设置截止期限调度程序ACTION ==“ add | change “,KERNEL ==” sd [az]“,ATTR {queue / rotational} ==” 0“,ATTR {queue / scheduler} =” deadline“
Dani_l 2015年

@Dani_l您应该对此进行扩展并将其添加为答案。
罗伯特·S·巴恩斯

1
有没有一种方法可以在运行时一次更改所有驱动器?同样,通过内核命令行参数“ elevator”设置默认调度程序。谢谢。
SkyRaT

20

可以使用udev规则让系统根据硬件的某些特性来决定调度程序。
用于SSD和其他非旋转驱动器的udev规则示例可能看起来像

# set noop scheduler for non-rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop"

在新的udev规则文件中(例如/etc/udev/rules.d/60-ssd-scheduler.rules)。该答案基于debian Wiki

要检查ssd磁盘是否将使用该规则,可以事先检查一下trigger属性:

for f in /sys/block/sd?/queue/rotational; do printf "$f "; cat $f; done

在自动检测非旋转介质并将IO调度程序仅应用于这些介质方面,这是一个很好的答案。建议截止日期不仅适用于非旋转媒体。Oracle建议针对数据库工作负载使用截止日期io调度程序。Oracle的建议可能来自这样一个事实,即截止日期可以比其他IO调度程序处理更好的同步写入。例如,查看/ sys / block / sdX / queue / iosched / writes_starved“最后期限”调度程序的可调参数(对于读取而言,没有这种可调参数)。如果数据库的同步重做写入不能很快完成,则数据库的性能可能会很差。
塔加

7

使内核支持不同内核的目的是您可以在不重新引导的情况下试用它们。然后,您可以通过系统运行测试工作负载,衡量性能,然后将其作为应用程序的标准工作负载。

在现代服务器级别的硬件上,只有noop才显得有用。其他人在我的测试中似乎较慢。


您如何在运行时实际更改它?
罗伯特·S·巴恩斯

noop相对于其他调度程序的性能在很大程度上取决于硬件和特定的负载。出于好奇,您正在运行哪些磁盘,控制器和测试?
短暂的

1
是的,当您拥有智能RAID控制器和其他东西(比内核更了解最佳访问模式)时,noop很好。截止日期也不错。
Zan Lynx

1
对于我来说,这纯粹是一次学习练习,在此过程中,我试图配置最小,最快的启动内核,以提供笔记本电脑所需的所有功能。我在“ Linux Kernel Development”和“ Essential Linux Device Drivers”中都进行了研究,但没有找到一个令人满意的答案,内核在运行时选择Scheduler有多聪明,或者总是使用默认值,除非您手动将其设置为其他内容?
罗伯特·S·巴恩斯

ephemient>在DELL PERC控制器上,也在DELL Powervault MD3000上。两者似乎都优于默认设置(CFQ)。
MarkR

0

您可以在启动时通过向内核cmdline添加“ elevator”参数来进行设置(例如在grub.cfg中)

例:

elevator=deadline

这将使“截止期限”成为所有块设备的默认I / O调度程序。

如果您想在系统启动后查询或更改调度程序,或者想为特定的块设备使用其他调度程序,建议您安装并使用ioschedset工具来简化此操作。

https://github.com/kata198/ioschedset

如果您使用的是Archlinux,则可以在aur中使用:

https://aur.archlinux.org/packages/ioschedset

一些示例用法:

# Get i/o scheduler for all block devices
[username@hostname ~]$ io-get-sched
sda:    bfq
sr0:    bfq

# Query available I/O schedulers
[username@hostname ~]$ io-set-sched --list
mq-deadline kyber bfq none

# Set sda to use "kyber"
[username@hostname ~]$ io-set-sched kyber /dev/sda
Must be root to set IO Scheduler. Rerunning under sudo...

[sudo] password for username:
+ Successfully set sda to 'kyber'!

# Get i/o scheduler for all block devices to assert change
[username@hostname ~]$ io-get-sched
sda:    kyber
sr0:    bfq

# Set all block devices to use 'deadline' i/o scheduler
[username@hostname ~]$ io-set-sched deadline
Must be root to set IO Scheduler. Rerunning under sudo...

+ Successfully set sda to 'deadline'!
+ Successfully set sr0 to 'deadline'!

# Get the current block scheduler just for sda
[username@hostname ~]$ io-get-sched sda
sda:    mq-deadline

用法应该是不言自明的。这些工具是独立的,仅需要bash。

希望这可以帮助!

编辑:免责声明,这些是我编写的脚本。


-3

Linux内核不会在运行时自动更改IO Scheduler。我的意思是,到目前为止,Linux内核无法根据辅助存储设备的类型自动选择“最佳”调度程序。在启动或运行期间,可以手动更改IO调度程序。

默认调度程序是在启动时根据/linux-2.6 /block/Kconfig.iosched文件中的内容选择的。但是,可以通过echo在/ sys / block / [DEV] / queue / scheduler中的文件中输入有效的调度程序名称来在运行时更改IO调度程序。例如,echo deadline > /sys/block/hda/queue/scheduler


8
我不明白为什么这个答案值得这么多赞成票。这实际上不是错误的。
DepressedDaniel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.