Linux I/O调度器介绍

网友投稿 909 2022-05-29

linux I/O调度器的总体目标是希望让磁头能够顺序访问,在较小的影响响应速度的前提下,提高I/O的吞吐量,类似电梯的原理,所以Linux的I/O调度算法也被称为电梯调度算法。下面就Linux常见的I/O调度程序进行介绍。

Noop(No Operation)

Noop是针对非传统机械硬盘(例如Dorado V3或内存设备)或自身具备I/O调度算法或较大缓存的环境,提供了最基本的合并和排序(FIFO)功能。NOOP调度器执行的唯一操作是合并,它以后向合并的方式合并了相邻的请求,除此之外,它是一个真正的无操作调度程序,它仅按FIFO顺序维护请求队列。注意,并不是存储足够快就应该选择Noop调度算法,还应该考虑主机的负载模型,如果系统是计算密集型(CPU-bound)且存储非常快(例如Dorado V3),Noop算法是一个不错的选择。

CFQ(Completely Fair Queuing)

CFQ尝试提供由发起I/O进程决定的公平的I/O调度,是RHEL5.x(内核版本2.6.18)上默认调度策略。CFQ提供三个不同的调度等级:实时real-time(RT),最佳效果best-effort(BE)和闲置idle。可使用 ionice 命令手动分配调度等级,或者使用ioprio_set系统调用编程分配。默认情况下将进程设定为"最佳效果"调度等级。实时调度等级和最佳效果调度等级又进一步分为八个 I/O 优先级,其中 0 代表最高优先权,7 代表最低优先权。采用实时调度等级的进程比采用最佳效果等级和闲置等级的进程会被更频繁地调度,因此所有实时等级的I/O都会在最佳效果等级或者闲置等级I/O前得到调度。这意味着实时优先权的I/O可能饿死最佳效果和闲置等级的I/O。最佳效果调度是默认调度等级,默认优先权为 4。闲置调度等级中的进程只有在系统中没有其他I/O等待时才会被执行。

CFQ通过为每个执行I/O的进程分配时间片段提供公平。在其时间片段中,进程每次最多可有八个请求(默认)。调度程序会尝试根据历史数据估计某个程序是否会在近期发出更多 I/O,如果认为该进程即将发出更多的I/O,CFQ会“空转”,等待即将下发的I/O,即使有其他进程正在等待发出 I/O。由于CFQ执行的“空转”等待操作,通常CFQ并不适合快速外置存储阵列或者固态硬盘,例如Dorado V3。如果要求在此类存储中使用CFQ(例如需要使用 cgroup加权I/O调度程序),则需要调节一些参数以改进CFQ性能。具体见RedHat Performance Tuning Guide.

CFQ是一个非工作保留(non-work-conserving)的I/O调度器,这意味着即使有待处理的请求,它也可以是空闲的。非工作保留调度器的堆栈会在I/O路径中引入大的延迟。例如,在基于主机的硬件RAID控制器的顶部使用CFQ,RAID控制器可以实现其自己的非工作保留调度器,从而在堆栈中引起两次延迟。

Deadline

最后期限I/O调度中每个请求是基于最后期限的,即每request会被分配一个time stamp,注意:只有当请求进入I/O调度程序后方开始计算时延(这个区别非常重要,因为可能会让程序进入睡眠等待模式以便释放请求描述符)。

读请求和写请求被分成了两个队列,每个队列(读或写)都采用两种方式将这些请求管理起来,一种是采用红黑树(RB tree)的方式将所有request组织起来,通过request的访问地址作为索引,即按照LBA顺序排序(单向递增);另一种方式是采用队列的方式将request管理起来,所有的request采用先来后到的方式进行排序,即FIFO队列。

默认情况下读取比写入的优先权高,因为程序更容易因读取I/O而被阻断,除非写请求即将被饿死的时候,才会去调度处理写请求。这种处理可以保证读请求的延迟时间最小化。

最后期限调度以批量的形式处理请求,对那些地址临近的顺序化请求,deadline给予了高优先级处理权,参数fifo_batch可指定一批包含的读取或写入个数,默认为16。

处理完一批I/O后,I/O调度程序会检查是否有写请求已等待太久,然后决定是否开始新一批读或者写操作,这样保证了每个请求的延迟时间。只在开始新一批I/O处理时才检查FIFO请求列表的过期请求,因此,如果选择批写入,且同时有过期的读取请求,那么只有在批写入完成后方可执行读取请求。

Anticipatory scheduler(AS)

该算法从Linux 2.6.33版本后被移除。Anticipatory基于“假空闲”(Deceptive idleness)的假设,意思是一个进程在刚刚做完一次读操作后,看似空闲,但可能是在处理这些数据,处理完后还会继续进行读操作,这个时候如果IO调度器去处理另外一个进程的请求,那么当原进程的下一个请求到来,磁头需要重新寻址,这样大大增加了时延。所以,Anticipatory算法会在一个读请求完成后,再等待一定时间,通常是6ms,如果6ms内这个进程上还有读请求过来,则继续服务,否则,处理下一个进程的读写请求。

配置I/O调度

下面示例查看sdc的调度策略,[cfq]表示当前的调度策略为cfq

# cat /sys/block/sdc/queue/scheduler

noop anticipatory deadline [cfq]

下面示例将sdc的调度策略临时修改为noop,服务器重启后将恢复默认

# echo noop > /sys/block/sdc/queue/scheduler

在内核启动参数指定调度策略,例如elevator=noop

kernel /boot/vmlinuz-2.6.32.54-0.3-default root=/dev/disk/by-id/scsi-3600508e00000000099853793bd56b80b-part1 resume=/dev/disk/by-id/scsi-3600508e00000000099853793bd56b80b-part2 splash=silent crashkernel=128M@32M  elevator=noop

参考

switching-sched.txt  https://www.kernel.org/doc/Documentation/block/switching-sched.txt

Veloces: An Efficient I/O Scheduler for Solid State Devices  https://www.kernel.org/doc/ols/2014/ols2014-rangnekar.pdf

Enhancements to Linux I/O Scheduling   https://www.kernel.org/doc/ols/2005/ols2005v2-pages-183-200.pdf

Workload Dependent Performance Evaluation of the Linux 2.6 I/O Schedulers  https://www.kernel.org/doc/ols/2004/ols2004v2-pages-139-162.pdf

Completely Fair Queuing (CFQ)

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/ch06s04.html

Linux中常见IO调度器  http://alanwu.blog.51cto.com/3652632/1393068

Linux I/O调度器介绍

Linux 任务调度

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Nginx(2):架构设计与工作流程
下一篇:我太南了!麻将十段的人工智能来了
相关文章