Linux I/O 調度算法

IO調度器的整體目標是但願讓磁頭可以老是往一個方向移動,移動到底了再往反方向走,這偏偏就是現實生活中的電梯模型,因此IO調度器也被叫作電梯. (elevator)而相應的算法也就被叫作電梯算法.而Linux中IO調度的電梯算法有好幾種,一個叫作as(Anticipatory),一個叫作 cfq(Complete Fairness Queueing),一個叫作deadline,還有一個叫作noop(No Operation).具體使用哪一種算法咱們能夠在啓動的時候經過內核參數elevator來指定.算法

1、I/O調度的4種算法

1)CFQ(徹底公平排隊I/O調度程序)

特色: 在最新的內核版本和發行版中,都選擇CFQ作爲默認的I/O調度器,對於通用的服務器也是最好的選擇. CFQ試圖均勻地分佈對I/O帶寬的訪問,避免進程被餓死並實現較低的延遲,是deadline和as調度器的折中. CFQ對於多媒體應用(video,audio)和桌面系統是最好的選擇. CFQ賦予I/O請求一個優先級,而I/O優先級請求獨立於進程優先級,高優先級的進程的讀寫不能自動地繼承高的I/O優先級.數據庫

工做原理: CFQ爲每一個進程/線程,單首創建一個隊列來管理該進程所產生的請求,也就是說每一個進程一個隊列,各隊列之間的調度使用時間片來調度, 以此來保證每一個進程都能被很好的分配到I/O帶寬.I/O調度器每次執行一個進程的4次請求.服務器

2)NOOP(電梯式調度程序)

特色: 在Linux2.4或更早的版本的調度程序,那時只有這一種I/O調度算法. NOOP實現了一個簡單的FIFO隊列,它像電梯的工做主法同樣對I/O請求進行組織,當有一個新的請求到來時,它將請求合併到最近的請求以後,以此來保證請求同一介質. NOOP傾向餓死讀而利於寫. NOOP對於閃存設備,RAM,嵌入式系統是最好的選擇. 電梯算法餓死讀請求的解釋: 由於寫請求比讀請求更容易. 寫請求經過文件系統cache,不須要等一次寫完成,就能夠開始下一次寫操做,寫請求經過合併,堆積到I/O隊列中. 讀請求須要等到它前面全部的讀操做完成,才能進行下一次讀操做.在讀操做之間有幾毫秒時間,而寫請求在這之間就到來,餓死了後面的讀請求.ionic

3)Deadline(截止時間調度程序)

特色: 經過時間以及硬盤區域進行分類,這個分類和合並要求相似於noop的調度程序. Deadline確保了在一個截止時間內服務請求,這個截止時間是可調整的,而默認讀期限短於寫期限.這樣就防止了寫操做由於不能被讀取而餓死的現象. Deadline對數據庫環境(ORACLE RAC,MYSQL等)是最好的選擇.ide

4)AS(預料I/O調度程序)

特色: 本質上與Deadline同樣,但在最後一次讀操做後,要等待6ms,才能繼續進行對其它I/O請求進行調度. 能夠從應用程序中預訂一個新的讀請求,改進讀操做的執行,但以一些寫操做爲代價. 它會在每一個6ms中插入新的I/O操做,而會將一些小寫入流合併成一個大寫入流,用寫入延時換取最大的寫入吞吐量. AS適合於寫入較多的環境,好比文件服務器 AS對數據庫環境表現不好.oop

2、查看系統配置

1.查看當前系統支持的IO調度算法

dmesg | grep -i scheduler [root@localhost ~]# dmesg | grep -i scheduler io scheduler noop registered io scheduler anticipatory registered io scheduler deadline registered io scheduler cfq registered (default)測試

2.查看當前系統的I/O調度方法:

cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq]ui

臨地更改I/O調度方法: 例如:想更改到noop電梯調度算法: echo noop > /sys/block/sda/queue/schedulerspa

3.永久的更改I/O調度方法:

修改內核引導參數,加入elevator=調度程序名 vi /boot/grub/menu.lst 更改到以下內容: kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet線程

重啓以後,查看調度方法: cat /sys/block/sda/queue/scheduler noop anticipatory [deadline] cfq 已是deadline了

3、I/O調度程序的測試

本次測試分爲只讀,只寫,讀寫同時進行. 分別對單個文件600MB,每次讀寫2M,共讀寫300次.

1.測試磁盤讀:

[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/sda1 f=/dev/null bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 6.81189 seconds, 92.4 MB/s real 0m6.833s user 0m0.001s sys 0m4.556s [root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/sda1 f=/dev/null bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 6.61902 seconds, 95.1 MB/s real 0m6.645s user 0m0.002s sys 0m4.540s [root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/sda1 f=/dev/null bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 8.00389 seconds, 78.6 MB/s real 0m8.021s user 0m0.002s sys 0m4.586s [root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/sda1 f=/dev/null bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 29.8 seconds, 21.1 MB/s real 0m29.826s user 0m0.002s sys 0m28.606s 結果: 第一 noop:用了6.61902秒,速度爲95.1MB/s 第二 deadline:用了6.81189秒,速度爲92.4MB/s 第三 anticipatory:用了8.00389秒,速度爲78.6MB/s 第四 cfq:用了29.8秒,速度爲21.1MB/s

2.測試寫磁盤:

[root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/zero f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 6.93058 seconds, 90.8 MB/s real 0m7.002s user 0m0.001s sys 0m3.525s [root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/zero f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 6.79441 seconds, 92.6 MB/s real 0m6.964s user 0m0.003s sys 0m3.489s [root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/zero f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 9.49418 seconds, 66.3 MB/s real 0m9.855s user 0m0.002s sys 0m4.075s [root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler [root@test1 tmp]# time dd if=/dev/zero f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 6.84128 seconds, 92.0 MB/s real 0m6.937s user 0m0.002s sys 0m3.447s 測試結果: 第一 anticipatory,用了6.79441秒,速度爲92.6MB/s 第二 deadline,用了6.84128秒,速度爲92.0MB/s 第三 cfq,用了6.93058秒,速度爲90.8MB/s 第四 noop,用了9.49418秒,速度爲66.3MB/s

3.測試同時讀/寫

[root@test1 tmp]# echo deadline > /sys/block/sda/queue/scheduler [root@test1 tmp]# dd if=/dev/sda1 f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 15.1331 seconds, 41.6 MB/s [root@test1 tmp]# echo cfq > /sys/block/sda/queue/scheduler [root@test1 tmp]# dd if=/dev/sda1 f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 36.9544 seconds, 17.0 MB/s [root@test1 tmp]# echo anticipatory > /sys/block/sda/queue/scheduler [root@test1 tmp]# dd if=/dev/sda1 f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 23.3617 seconds, 26.9 MB/s [root@test1 tmp]# echo noop > /sys/block/sda/queue/scheduler [root@test1 tmp]# dd if=/dev/sda1 f=/tmp/test bs=2M count=300 300+0 records in 300+0 records out 629145600 bytes (629 MB) copied, 17.508 seconds, 35.9 MB/s 測試結果: 第一 deadline,用了15.1331秒,速度爲41.6MB/s 第二 noop,用了17.508秒,速度爲35.9MB/s 第三 anticipatory,用了23.3617秒,速度爲26.9MS/s 第四 cfq,用了36.9544秒,速度爲17.0MB/s

4、ionice更改任務的類型和優先級

ionice能夠更改任務的類型和優先級,不過只有cfq調度程序能夠用ionice. 有三個例子說明ionice的功能: 採用cfq的實時調度,優先級爲7 ionice -c1 -n7 -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300& 採用缺省的磁盤I/O調度,優先級爲3 ionice -c2 -n3 -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300& 採用空閒的磁盤調度,優先級爲0 ionice -c3 -n0 -ptime dd if=/dev/sda1 f=/tmp/test bs=2M count=300& ionice的三種調度方法,實時調度最高,其次是缺省的I/O調度,最後是空閒的磁盤調度. ionice的磁盤調度優先級有8種,最高是0,最低是7. 注意,磁盤調度的優先級與進程nice的優先級沒有關係. 一個是針對進程I/O的優先級,一個是針對進程CPU的優先級.

Anticipatory I/O scheduler 適用於大多數環境,但不太合適數據庫應用 Deadline I/O scheduler 一般與Anticipatory至關,但更簡潔小巧,更適合於數據庫應用 CFQ I/O scheduler 爲全部進程分配等量的帶寬,適合於桌面多任務及多媒體應用,默認IO調度器 Default I/O scheduler

相關文章
相關標籤/搜索