I/O
调度算法,也称I/O
调度策略。
前言
现代计算机体系中,硬盘是数据存储的持久化介质,硬盘的访问速度相比内存存在数量级的差距,因此有效的调度能更好利用资源,优化响应。
和CPU
调度算法相似,调度的本质是对请求排序。在Linux
系统中,这由I/O
调度层负责。
在I/O
调度之前,如果多个I/O
在同一个sector中,或者是相邻sector。Linux
可以把多个请求合并为一个来减少请求数量。这是在Block
层处理的,可以设置开启或关闭。
算法
Linus电梯
早期Linux
的I/O
调度算法被称之为电梯算法。
因为硬盘的寻道操作类似于升降电梯,所以最初的算法就是被称作电梯算法也叫扫描(SCAN
)算法。下列实际应用的算法中Deadline scheduler
和Anticipatory scheduler
使用了电梯算法为基础,根据某些任务情况作一定调整。
特点:类比电梯运行,也就是顺向截车的原则。即机械臂一定向相同方向扫描完所有请求的磁道,再换个方向运行,反复循环。
优点:有效减少寻道时间。
缺点:没有处理请求饥饿,如果某个磁道中一直有请求占用着,会影响某些请求及时响应。
Deadline scheduler(截止时间调度程序)
为了解决linus
电梯中请求饥饿的问题,产生了Deadline scheduler
算法。
特点:继承linus
电梯的办法,增加了特殊情况的处理。即增加了读请求队列和写请求队列的带超时FIFO队列,当读和写请求的队列中的请求超时,会优先处理这些请求,减缓请求饥饿的情况,读请求优先级高于写请求。
优点:缓解请求饥饿情况,适用于对响应时间敏感的业务,比如数据库。
缺点:牺牲全局吞吐量。
Anticipatory scheduler(预测算法)
在Deadline scheduler基础上优化了顺序请求的情况。
特点:继承Deadline scheduler
算法,在处理完一个I/O请求之后会等待6ms(默认),如果此时有当前扇区相邻的请求,则直接处理这个请求。等待时间结束后才会去处理原本的下一个请求。
优点:当系统大量存在顺序请求时,节约大量的寻道时间。
缺点:每次I/O完成后,都需要6ms的延时。
CFQ(Completely Fair Queuing)
完全公平队列算法,当前linux
系统默认调度算法。
特点:按照优先级分组,优先处理高优先级。主要算法为时间片轮片。类似分时操作系统的进程调度。
优点:高优先级的响应及时,也不会产生访问饿死情况。
None/NOOP(No Operation)
新的内核已经将命名从Noop
改为None
。
无操作调度算法,就是什么都不操作。让硬盘做更多的事情,能者多劳。
特点:对系统的负担最小。适合于无寻道的存储设备,也就是固态硬盘(SSD
)。
优点:适合随机访问。
选择建议
目前较为常用的调度算法是CFQ
,Deadline
,None
。通常情况,硬盘性能越好,选越靠后的。但实际使用时,应当以测试为准。
- 如果使用高性能固态硬盘,比如使用
NVME
协议,使用M.2
或PCIE
接口的硬盘。建议使用None
调度算法。 - 如果业务对延迟要求非常高,比如数据库类应用,通常会选用
Deadline
算法。 - 对于云服务器的分布式块存储,则需要根据块存储的性能判断。
配置方法
查看系统支持的I/O调度算法
dmesg|grep -i scheduler
查看硬盘的当前I/O调度算法
cat /sys/block/<dev>/queue/scheduler
设置IO调度算法
echo ${调度算法名称} > /sys/block/<dev>/queue/scheduler
总结
- 机械硬盘时期,电梯算法有着最好的寻道,但任务总归有一定优先级的,所以单纯的电梯算法并不适用更复杂的需求。
- 目前默认的
CFQ
算法采用了时间片轮训,类似于进程调度。相比之下,CPU
任务调度算法比I/O
调度算法要复杂些,但看得出它们都是时间片轮询的方式。 - 随着硬件性能和能力的提升,操作系统把功能
Offload
到硬件会成为一个趋势。
暂无评论内容