Linux实现了4种I/O调度算法,分别为:NOOP算法(no operate)、最后期限算法(Deadline)、完全公平队列算法(CFQ)和预期算法(Anticipatory)。
NOOP算法
不对I/O请求排序,但会合并请求,除此之外无其他任何优化。它用FIFO队列顺序提交I/O请求。NOOP算法适用于如SSD的随机访问设备,因为随机访问设备不存在磁头移动造成的寻道时间,无需做多余的事情。
最后期限算法
最后期限算法维护了三个队列,分别是具备合并和排序功能的请求队列、读请求队列和写请求队列。这三个队列均为带有超时时间的FIFO队列。当有新的I/O请求时,会被同时插入普通队列和读/写队列,然后I/O调度器正常处理普通队列中的请求。当调度器发现读/写请求队列中有请求即将超时时,会优先处理这些请求,以保证尽量不产生饥饿请求。
此算法在全局吞吐量和延迟方面做了权衡,牺牲了一定的全局吞吐量来避免饥饿请求的可能。当系统存在大量顺序I/O请求的时候,此算法可能导致I/O请求无法被很好的排序,引发频繁寻道。
完全公平队列算法
每个提交I/O请求的进程都会有自己的I/O队列,此算法将I/O请求按照进程分别放入进程对应的队列中。CFQ的公平是针对进程而言的,它以时间片算法为前提,轮转调动队列,默认从当前队列中取出4个I/O请求处理,然后处理下一个队列中的4个请求,确保每个进程享有的I/O资源是均衡的。
预期算法
是基于预测的I/O算法,和最后期限算法类似,维护了三个队列。但是此算法在处理完一个I/O请求之后不会立即返回处理下一个请求,而是等待片刻(默认6ms),等待期间如果有新来的相邻扇区的请求,会直接处理此新来的相邻扇区的请求。当等待时间结束后,才会处理下一个队列的请求。此算法适合写入较多的环境,不适合MySQL等随机读取较多的数据库环境。