2009-06-17 34 views
76

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

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

默认是完全公平排队调度程序。我想知道的是,如果在我的定制内核中包含所有四个调度程序有任何用处。除非内核足够聪明,为正确的硬件选择正确的调度程序,特别是基于闪存的驱动器的“noop”调度程序和传统的其他调度程序之一,否则看起来没有太多的关注将多个调度程序编译进去硬盘。

这是这种情况?

回答

103

/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历史悠久为了在这些工作负载上获得最佳性能而进行调优,并且将所有请求快速传递到底层设备。

7

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

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

+0

你怎么竟在运行时改变它? – 2009-06-17 21:48:15

+0

noop相对于其他调度器的性能非常依赖于硬件和特定的负载。出于好奇,你正在运行什么磁盘,控制器和测试? – ephemient 2009-06-18 03:02:32

+1

是的,当你拥有智能RAID控制器和其他知道比内核更好的访问模式的东西时,noop是很好的选择。截止日期也不错。 – 2009-06-18 03:23:32

-5

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

默认调度程序在启动时根据位于/linux-2.6的文件中的内容选择。/block/Kconfig.iosched。然而,有可能通过echo荷兰国际集团的有效调度名称到位于/ SYS /块/ [DEV] /队列/调度此文件来改变在运行时间期间的IO调度器。例如,echo deadline > /sys/block/hda/queue/scheduler

17

它可以使用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磁盘是否会使用规则,有可能提前检查触发属性:

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