现代计算机体系中,机械磁盘是主要存储设备。机械磁盘的访问是瓶颈,主要因为寻道时间长。所以操作系统会根据寻道进行一定优化,在Linux系统汇总,I/O调度层就做这个处理的。
因为I/O时间主要花费在寻道上,所以尽量减少寻道时间。通过合并I/O请求和I/O调度算法。
- 合并I/O请求:merge操作,如果多个I/O在同一个sector中,或者是相邻sector。把多个请求合并为同一个或一个相邻的sectors的请求。减少寻道指令。
- I/O调度算法:通过算法减少机械臂转动。
寻道操作类似于升降电梯,所以最初的算法就是被称作电梯算法也叫扫描(SCAN)算法。下列实际应用的算法中Deadline scheduler和Anticipatory scheduler使用了电梯算法为基础,根据某些任务情况作一定调整。
Linus电梯:
早期Linux的I/O调度算法,包括merge和电梯寻道。
特点:类比电梯运行,也就是顺向截车的原则。即机械臂一定向相同方向扫描完所有请求的磁道,再换个方向运行,反复循环。
优点:减少寻道时间。
缺点:没有处理请求饥饿,如果某个磁道中一直有请求占用着,会影响某些请求及时响应。
Deadline scheduler (截止时间调度程序):
为了解决linus电梯中请求饥饿的问题,产生了Deadline scheduler算法。
特点:继承linus电梯的办法,增加了特殊情况的处理。即增加了读请求队列和写请求队列的带超时FIFO队列,当读和写请求的队列中的请求超时,会优先处理这些请求,减缓请求饥饿的情况,读请求优先级高于写请求。
优点:缓解请求饥饿情况。
缺点:牺牲一些全局吞吐量。
Anticipatory scheduler(预测算法)
在Deadline scheduler基础上优化了顺序请求的情况。
特点:继承Deadline scheduler算法,在处理完一个I/O请求之后会等待6ms(默认),如果此时有当前扇区相邻的请求,则直接处理这个请求。等待时间结束后才会去处理原本的下一个请求。
优点:当系统大量存在顺序请求时,节约大量的寻道时间。
缺点:每次I/O完成后,都需要6ms的延时。
CFQ(Completely Fair Queuing)
完全公平队列算法,当前linux系统默认调度算法
特点:按照优先级分组,优先处理高优先级。主要算法为时间片轮片。类似分时操作系统的进程调度。
优点:高优先级的响应及时,也不会产生访问饿死情况。
NOOP(No Operation)
无操作调度算法,就是什么都不操作,除了merge操作。
特点:低CPU使用率。因为没啥算法。适合于无寻道的存储设备,比如SSD,Flash等。
优点:适合随机访问。
两个命令:
1 | dmesg| grep -i scheduler #查看系统支持的调度算法 |
2 | cat /sys/block/ <dev> /queue/scheduler #查看磁盘的当前调度算法 |
3 | echo 调度算法名称 > /sys/block/ <dev> /queue/scheduler |
总结:
固态硬盘发展让NOOP成为未来趋势。
机械硬盘时期,电梯算法有着最好的寻道,但任务总归有一定优先级的,所以单纯的电梯算法并不适用。
目前默认的CFQ算法采用了时间片轮训,类似于进程调度。相比之下,进程调度的算法比I/O调度算法要复杂些,但看得出目前主流都是使用了时间片轮询。
转载请注明:旅途@KryptosX » linux I/O调度层总结