一. IO調度器(IO Scheduler)是作業系統用來決定塊裝置上IO操作提交順序的方法。存在的目的有兩個,一是提高IO輸送量,二是降低IO回應時間。然而IO輸送量和IO回應時間往往是矛盾的,為了盡量平衡這兩者,IO調度器提供了多種調度演算法來適應不同的IO請求情境。其中,對資料庫這種隨機讀寫的情境最有利的演算法是DEANLINE。接著我們按照從簡單到複雜的順序,下面是Linux 2.6核心提供的幾種IO調度演算法。
1、NOOP
NOOP演算法的全寫為No Operation。該演算法實現了最最簡單的FIFO隊列,所有IO請求大致按照先來後到的順序進行操作。之所以說“大致”,原因是NOOP在FIFO的基礎上還做了相鄰IO請求的合并,並不是完完全全按照先進先出的規則滿足IO請求。
假設有如下的io請求序列:
100,500,101,10,56,1000
NOOP將會按照如下順序滿足:
100(101),500,10,56,1000
2、CFQ
CFQ演算法的全寫為Completely Fair Queuing。該演算法的特點是按照IO請求的地址進行排序,而不是按照先來後到的順序來進行響應。
假設有如下的io請求序列:
100,500,101,10,56,1000
CFQ將會按照如下順序滿足:
100,101,500,1000,10,56
在傳統的SAS盤上,磁碟尋道花去了絕大多數的IO回應時間。CFQ的出發點是對IO地址進行排序,以盡量少的磁碟旋轉次數來滿足儘可能多的IO請求。在CFQ演算法下,SAS盤的輸送量大大提高了。但是相比於NOOP的缺點是,先來的IO請求並不一定能被滿足,可能會出現餓死的情況。
3、DEADLINE
DEADLINE在CFQ的基礎上,解決了IO請求餓死的極端情況。除了CFQ本身具有的IO排序隊列之外,DEADLINE額外分別為讀IO和寫IO提供了FIFO隊列。讀FIFO隊列的最大等待時間為500ms,寫FIFO隊列的最大等待時間為5s。FIFO隊列內的IO請求優先順序要比CFQ隊列中的高,,而讀FIFO隊列的優先順序又比寫FIFO隊列的優先順序高。優先順序可以表示如下:
FIFO(Read) > FIFO(Write) > CFQ
4、ANTICIPATORY
CFQ和DEADLINE考慮的焦點在於滿足零散IO請求上。對於連續的IO請求,比如順序讀,並沒有做最佳化。為了滿足隨機IO和順序IO混合的情境,Linux還支援ANTICIPATORY調度演算法。ANTICIPATORY的在DEADLINE的基礎上,為每個讀IO都設定了6ms的等待時間視窗。如果在這6ms內OS收到了相鄰位置的讀IO請求,就可以立即滿足。
二. Linux作業系統IO調度器演算法的查看和修改(以CentOS5.5為例):
[root@dbserver2 ~]# cat /etc/RedHat-release
CentOS release 5.5 (Final)
[root@dbserver2 ~]# uname -a
Linux dbserver2 2.6.18-194.el5 #1 SMP Fri Apr 2 14:58:14 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
1.機器為2.6核心,查看IO調度演算法設定的方法:
[root@dbserver2 ~]# fdisk -l
Disk /dev/sda: 598.8 GB, 598879502336 bytes
255 heads, 63 sectors/track, 72809 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 13 104391 83 Linux
/dev/sda2 14 65669 527381820 83 Linux
/dev/sda3 65670 68219 20482875 83 Linux
/dev/sda4 68220 72809 36869175 5 Extended
/dev/sda5 68220 70769 20482843+ 83 Linux
/dev/sda6 70770 72809 16386268+ 82 Linux swap / Solaris
[root@dbserver2 ~]#
[root@dbserver2 ~]# find / -iname "scheduler"
/sys/block/sr0/queue/scheduler
/sys/block/sda/queue/scheduler
查看系統當前IO調度演算法
[root@dbserver2 ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq] ----括弧中為當前使用的演算法
2.修改IO調度演算法:
[root@test80 ~]# echo deadline > /sys/block/sda/queue/scheduler
[root@test80 ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq 可以看到IO調度演算法已經修改為deadline
三. 針對MYSQL資料庫伺服器的IO調度演算法最佳化設定:
1.CFQ使用於IO大小非常均勻的情境
2.比較複雜的OLTP環境最好使用DeadLine演算法
3.IO效能不是瓶頸的時候可以使用Noop演算法
4.Anticipatory不適合資料庫環境,DB伺服器不要使用這種演算法。
5.新興的固態硬碟比如SSD、Fusion IO上,最簡單的NOOP反而可能是最好的演算法,因為其他三個演算法的最佳化是基於縮短尋道時間的,而固態硬碟沒有所謂的尋道時間且IO回應時間非常短。