I/O 调度算法再各个进程竞争磁盘I/O 的时候担当了裁判的角色。他要求请求的次序和时机做最优化的处理,以求得尽可能最好的整体I/O 性能。
在linux 下面列出4 种调度算法:
CFQ (Completely Fair Queuing 完全公平的排队)(elevator=cfq):
这是默认算法,对于通用服务器来说通常是最好的选择。它试图均匀地分布对I/O 带宽的访问。在多媒体应用, 总能保证audio、video 及时从磁盘读取数据。但对于其他各类应用表现也很好。每个进程一个queue,每个queue 按照上述规则进行merge 和sort。进程之间round robin 调度,每次执行一个进程的4 个请求。
Deadline (elevator=deadline):
这个算法试图把每次请求的延迟降至最低。该算法重排了请求的顺序来提高性能。
NOOP (elevator=noop):
这个算法实现了一个简单FIFO 队列。他假定I/O 请求由驱动程序或者设备做了优化或者重排了顺序(就像一个智能控制器完成的工作那样)。在有些SAN 环境下,这个选择可能是最好选择。适用于随机存取设备, no seek cost,非机械可随机寻址的磁盘。
Anticipatory (elevator=as):
这个算法推迟I/O 请求,希望能对它们进行排序,获得最高的效率。同deadline 不同之处在于每次处理完读请求之后, 不是立即返回, 而是等待几个微妙在这段时间内, 任何来自临近区域的请求都被立即执行. 超时以后, 继续原来的处理.基于下面的假设: 几个微妙内, 程序有很大机会提交另一次请求.调度器跟踪每个进程的io 读写统计信息, 以获得最佳预期.
linux 中IO 调度方法的查看和设置的方法:
查看当前IO
cat /sys/block/{DEVICE-NAME}/queue/scheduler
cat /sys/block/sd*/queue/scheduler
例:输出结果如下
noop anticipatory deadline [cfq]
设置当前IO
echo {SCHEDULER-NAME} > /sys/block/{DEVICE-NAME}/queue/scheduler
echo noop > /sys/block/hda/queue/scheduler
对IO 调度使用的建议:
Deadline I/O scheduler 使用轮询的调度器,简洁小巧,提供了最小的读取延迟和尚佳的吞吐量,特别适合于读取较多的环境(比如数据库,Oracle 10G 之类).
Anticipatory I/O scheduler 假设一个块设备只有一个物理查找磁头(例如一个单独的SATA 硬盘),将多个随机的小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量.适用于大多数环境,特别是写入较多的环境(比如文件服务 器)Web,App 等应用我们可以采纳as 调度.
CFQ I/O scheduler 使用QoS 策略为所有任务分配等量的带宽,避免进程被饿死并实现了较低的延迟,可以认为是上述两种调度器的折中.适用于有大量进程的多用户系统,我在生产环境中测试 过一台机器本来流量只有350M 的样子,有时压力就不行了,流量也上不去了,因为读比较多,所以使用deadline 后,流量上升了50M,从流量之类的图上也见到稳定很多.
linux 启动时设置默认IO 调度
让系统启动时就使用默认的IO 方法,只需在grub.conf 文件中加入类似如下行
kernel /vmlinuz-2.6.24 ro root=/dev/sda1 elevator=deadline
有关IO 的几个内核参数
/proc/sys/vm/dirty_ratio
这个参数控制文件系统的文件系统写缓冲区的大小,单位是百分比,表示系统内存的百分比,表示当写缓冲使用到系统内存多少的时候,开始向磁盘写出数据。增大 之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般启动上缺省是10。下面 是增大的方法:
echo ‘40′> /proc/sys/vm/dirty_ratio
/proc/sys/vm/dirty_background_ratio
这个参数控制文件系统的pdflush 进程,在何时刷新磁盘。单位是百分比,表示系统内存的百分比,意思是当写缓冲使用到系统内存多少的时候, pdflush 开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一 般启动上缺省是5。下面是增大的方法:
echo ‘20′ > /proc/sys/vm/dirty_background_ratio
/proc/sys/vm/dirty_writeback_centisecs
这个参数控制内核的脏数据刷新进程pdflush 的运行间隔。单位是1/100 秒。缺省数值是500,也就是5 秒。如果你的系统是持续地写入动作,那么实际上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。设置方法如下:
echo ‘200′ > /proc/sys/vm/dirty_writeback_centisecs
如果你的系统是短期地尖峰式的写操作,并且写入数据不大(几十M/次)且内存有比较多富裕,那么应该增大此数值:
echo ‘1000′ > /proc/sys/vm/dirty_writeback_centisecs
/proc/sys/vm/dirty_expire_centisecs
这个参数声明Linux 内核写缓冲区里面的数据多“旧”了之后,pdflush 进程就开始考虑写到磁盘中去。单位是1/100 秒。缺省是30000,也就是30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO 提高太快。建议设置为1500,也就是15 秒算旧。
echo ‘1500′ > /proc/sys/vm/dirty_expire_centisecs
当然,如果你的系统内存比较大,并且写入模式是间歇式的,并且每次写入的数据不大(比如几十M),那么这个值还是大些的好。
本文出自 “Torvalds0310” 博客,请务必保留此出处http://torvalds0310.blog.51cto.com/2120200/1012155