在Linux 2.6中,有四種關(guān)于IO的調(diào)度算法,下面綜合小結(jié)一下:
1) NOOP
NOOP算法的全寫為No Operation。該算法實(shí)現(xiàn)了最最簡(jiǎn)單的FIFO隊(duì)列,所有IO請(qǐng)求大致按照先來后到的順序進(jìn)行操作。之所以說“大致”,
原因是NOOP在FIFO的基礎(chǔ)上還做了相鄰IO請(qǐng)求的合并,并不是完完全全按照先進(jìn)先出的規(guī)則滿足IO請(qǐng)求。NOOP假定I/O請(qǐng)求由驅(qū)動(dòng)程序或者設(shè)
備做了優(yōu)化或者重排了順序(就像一個(gè)智能控制器完成的工作那樣)。在有些SAN環(huán)境下,這個(gè)選擇可能是最好選擇。Noop 對(duì)于 IO 不那么操
心,對(duì)所有的 IO請(qǐng)求都用 FIFO 隊(duì)列形式處理,默認(rèn)認(rèn)為 IO 不會(huì)存在性能問題。這也使得 CPU 也不用那么操心。www.linuxidc.com當(dāng)然
,對(duì)于復(fù)雜一點(diǎn)的應(yīng)用類型,使用這個(gè)調(diào)度器,用戶自己就會(huì)非常操心。
2) Deadline scheduler
DEADLINE在CFQ的基礎(chǔ)上,解決了IO請(qǐng)求餓死的極端情況。除了CFQ本身具有的IO排序隊(duì)列之外,DEADLINE額外分別為讀IO和寫IO提供了FIFO
隊(duì)列。讀FIFO隊(duì)列的最大等待時(shí)間為500ms,寫FIFO隊(duì)列的最大等待時(shí)間為5s。FIFO隊(duì)列內(nèi)的IO請(qǐng)求優(yōu)先級(jí)要比CFQ隊(duì)列中的高,,而讀FIFO
隊(duì)列的優(yōu)先級(jí)又比寫FIFO隊(duì)列的優(yōu)先級(jí)高。優(yōu)先級(jí)可以表示如下:
FIFO(Read) > FIFO(Write) > CFQ
deadline 算法保證對(duì)于既定的 IO 請(qǐng)求以最小的延遲時(shí)間,從這一點(diǎn)理解,對(duì)于 DSS 應(yīng)用應(yīng)該會(huì)是很適合的。
3) Anticipatory scheduler
CFQ和DEADLINE考慮的焦點(diǎn)在于滿足零散IO請(qǐng)求上。對(duì)于連續(xù)的IO請(qǐng)求,比如順序讀,并沒有做優(yōu)化。為了滿足隨機(jī)IO和順序IO混合的場(chǎng)景,
Linux還支持ANTICIPATORY調(diào)度算法。ANTICIPATORY的在DEADLINE的基礎(chǔ)上,為每個(gè)讀IO都設(shè)置了6ms 的等待時(shí)間窗口。如果在這6ms內(nèi)OS收
到了相鄰位置的讀IO請(qǐng)求,就可以立即滿足
Anticipatory scheduler(as) 曾經(jīng)一度是 Linux 2.6 Kernel 的 IO scheduler 。Anticipatory 的中文含義是”預(yù)料的, 預(yù)想的”, 這個(gè)
詞的確揭示了這個(gè)算法的特點(diǎn),簡(jiǎn)單的說,有個(gè) IO 發(fā)生的時(shí)候,如果又有進(jìn)程請(qǐng)求 IO 操作,則將產(chǎn)生一個(gè)默認(rèn)的 6 毫秒猜測(cè)時(shí)間,猜測(cè)
下一個(gè) 進(jìn)程請(qǐng)求 IO 是要干什么的。這對(duì)于隨即讀取會(huì)造成比較大的延時(shí),對(duì)數(shù)據(jù)庫應(yīng)用很糟糕,而對(duì)于 Web Server 等則會(huì)表現(xiàn)的不錯(cuò)。
這個(gè)算法也可以簡(jiǎn)單理解為面向低速磁盤的,因?yàn)槟莻€(gè)”猜測(cè)”實(shí)際上的目的是為了減少磁頭移動(dòng)時(shí)間。
4)CFQ
CFQ算法的全寫為Completely Fair Queuing。該算法的特點(diǎn)是按照IO請(qǐng)求的地址進(jìn)行排序,而不是按照先來后到的順序來進(jìn)行響應(yīng)。
在傳統(tǒng)的SAS盤上,磁盤尋道花去了絕大多數(shù)的IO響應(yīng)時(shí)間。CFQ的出發(fā)點(diǎn)是對(duì)IO地址進(jìn)行排序,以盡量少的磁盤旋轉(zhuǎn)次數(shù)來滿足盡可能多的
IO請(qǐng)求。在CFQ算法下,SAS盤的吞吐量大大提高了。但是相比于NOOP的缺點(diǎn)是,先來的IO請(qǐng)求并不一定能被滿足,可能會(huì)出現(xiàn)餓死的情況。
Completely Fair Queuing (cfq, 完全公平隊(duì)列) 在 2.6.18 取代了 Anticipatory scheduler 成為 Linux Kernel 默認(rèn)的 IO scheduler
。cfq 對(duì)每個(gè)進(jìn)程維護(hù)一個(gè) IO 隊(duì)列,各個(gè)進(jìn)程發(fā)來的 IO 請(qǐng)求會(huì)被 cfq 以輪循方式處理。也就是對(duì)每一個(gè) IO 請(qǐng)求都是公平的。這使得
cfq 很適合離散讀的應(yīng)用(eg: OLTP DB)。我所知道的企業(yè)級(jí) Linux 發(fā)行版中,SUSE Linux 好像是最先默認(rèn)用 cfq 的.
查看和修改IO調(diào)度器的算法非常簡(jiǎn)單。假設(shè)我們要對(duì)sda進(jìn)行操作,如下所示:
cat /sys/block/sda/queue/scheduler
echo “cfq” > /sys/block/sda/queue/scheduler
總結(jié):
1 CFQ和DEADLINE考慮的焦點(diǎn)在于滿足零散IO請(qǐng)求上。對(duì)于連續(xù)的IO請(qǐng)求,比如順序讀,并沒有做優(yōu)化。為了滿足隨機(jī)IO和順序IO混合的場(chǎng)景
,Linux還支持ANTICIPATORY調(diào)度算法。ANTICIPATORY的在DEADLINE的基礎(chǔ)上,為每個(gè)讀IO都設(shè)置了6ms的等待時(shí)間窗口。如果在這6ms內(nèi)OS收
到了相鄰位置的讀IO請(qǐng)求,就可以立即滿足。
IO調(diào)度器算法的選擇,既取決于硬件特征,也取決于應(yīng)用場(chǎng)景。
在傳統(tǒng)的SAS盤上,CFQ、DEADLINE、ANTICIPATORY都是不錯(cuò)的選擇;對(duì)于專屬的數(shù)據(jù)庫服務(wù)器,DEADLINE的吞吐量和響應(yīng)時(shí)間都表現(xiàn)良好。
然而在新興的固態(tài)硬盤比如SSD、Fusion IO上,最簡(jiǎn)單的NOOP反而可能是最好的算法,因?yàn)槠渌齻€(gè)算法的優(yōu)化是基于縮短尋道時(shí)間的,而
固態(tài)硬盤沒有所謂的尋道時(shí)間且IO響應(yīng)時(shí)間非常短。
2 對(duì)于數(shù)據(jù)庫應(yīng)用, Anticipatory Scheduler 的表現(xiàn)是最差的。Deadline 在 DSS 環(huán)境表現(xiàn)比 cfq 更好一點(diǎn),而 cfq 綜合來看表現(xiàn)更好一
些。這也難怪 RHEL 4 默認(rèn)的 IO 調(diào)度器設(shè)置為 cfq. 而 RHEL 4 比 RHEL 3,整體 IO 改進(jìn)還是不小的。