选择Linux I / O调度程序

时间:2009-06-17 21:22:12

标签: linux linux-kernel scheduling

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

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

默认是完全公平的排队调度程序。我想知道的是,在我的自定义内核中包含所有四个调度程序是否有任何用处。除非内核足够智能为正确的硬件选择正确的调度程序,特别是基于闪存的驱动器的“noop”调度程序和传统的其他调度程序之一,似乎编译多个调度程序并不重要。硬盘。

是这样的吗?

5 个答案:

答案 0 :(得分: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通常是内存支持的块设备(例如ramdisks)和其他非旋转媒体(flash)的最佳选择,其中尝试重新安排I / O是浪费资源
  • deadline是一个轻量级的调度程序,试图对延迟进行严格限制
  • cfq尝试维持系统范围的I / O带宽公平性

默认值为anticipatory很长一段时间,它收到了很多调整,但在 2.6.33 (2010年初)中删除了。 cfq在不久前成为默认值,因为它的性能合理,公平性是多用户系统(甚至是单用户桌面)的一个很好的目标。对于某些情况 - 数据库通常用作示例,因为它们往往具有自己特有的调度和访问模式,并且通常是重要服务(所以谁关心公平?) - anticipatory长期以来可以在这些工作负载上实现最佳性能调整,deadline可以非常快速地将所有请求传递到底层设备。

答案 1 :(得分:19)

可以使用udev规则让系统根据hw的某些特性决定调度程序。
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磁盘是否使用该规则,可以提前检查触发器属性:

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

答案 2 :(得分:7)

让内核支持不同内核的目的是你可以在不重启的情况下试用它们;然后,您可以通过sytsem运行测试工作负载,测量性能,然后将其作为应用程序的标准工作负载。

在现代服务器级硬件上,只有noop的硬件才有用。其他人在我的测试中看起来比较慢。

答案 3 :(得分: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。

希望这会有所帮助!

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

答案 4 :(得分:-5)

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