磁盤IO調度算法


I/O 調度算法在各個進程競爭磁盤I/O的時候擔當了裁判的角色。他要求請求的次序和時機做最優化的處理,以求得盡可能最好的整體I/O性能。

Linux 4.0 IO協議棧框架圖

 

 

I/O調度程序的總結:

1)當向設備寫入數據塊或是從設備讀出數據塊時,請求都被安置在一個隊列中等待完成.
2)每個塊設備都有它自己的隊列.
3)I/O調度程序負責維護這些隊列的順序,以更有效地利用介質.I/O調度程序將無序的I/O操作變為有序的I/O操作.
4)內核必須首先確定隊列中一共有多少個請求,然后才開始進行調度.

 

I/O調度的4種算法:

CFQ(完全公平排隊I/O調度程序)

 

在最新的內核版本和發行版中,都選擇CFQ做為默認的I/O調度器,對於通用的服務器也是最好的選擇。CFQ對於多媒體應用(video,audio)和桌面系統是最好的選擇。CFQ賦予I/O請求一個優先級,而I/O優先級請求獨立於進程優先級,高優先級的進程的讀寫不能自動地繼承高的I/O優先級。

對於很多IO壓力較大的場景就並不是很適應,尤其是IO壓力集中在某些進程上的場景。因為這種場景我們需要更多的滿足某個或者某幾個進程的IO響應速度,而不是讓所有的進程公平的使用IO,比如數據庫應用。


CFQ試圖均勻地分布對I/O帶寬的訪問,避免進程被餓死並實現較低的延遲,是deadline和as調度器的折中.


工作原理:
CFQ為每個進程/線程,單獨創建一個隊列來管理該進程所產生的請求,也就是說每個進程一個隊列,每個隊列按照上述規則進行merge和sort。各隊列之間的調度使用時間片來調度,以此來保證每個進程都能被很好的分配到I/O帶寬.I/O調度器每次執行一個進程的4次請求。可以調 queued 和 quantum 來優化

 

NOOP(電梯式調度程序)


在Linux2.4或更早的版本的調度程序,那時只有這一種I/O調度算法.I/O請求被分配到隊列,調度由硬件進行,只有當CPU時鍾頻率比較有限時進行。

Noop對於I/O不那么操心,對所有的I/O請求都用FIFO隊列形式處理,默認認為 I/O不會存在性能問題。這也使得CPU也不用那么操心。它像電梯的工作主法一樣對I/O請求進行組織,當有一個新的請求到來時,它將請求合並到最近的請求之后,以此來保證請求同一介質.

NOOP傾向餓死讀而利於寫.
NOOP對於閃存設備,RAM,嵌入式系統是最好的選擇.

電梯算法餓死讀請求的解釋:
因為寫請求比讀請求更容易.
寫請求通過文件系統cache,不需要等一次寫完成,就可以開始下一次寫操作,寫請求通過合並,堆積到I/O隊列中.
讀請求需要等到它前面所有的讀操作完成,才能進行下一次讀操作.在讀操作之間有幾毫秒時間,而寫請求在這之間就到來,餓死了后面的讀請求.

 

Deadline(截止時間調度程序)


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

deadline實現了四個隊列,其中兩個分別處理正常read和write,按扇區號排序,進行正常io的合並處理以提高吞吐量.因為IO請求可能會集中在某些磁盤位置,這樣會導致新來的請求一直被合並,於是可能會有其他磁盤位置的io請求被餓死。於是實現了另外兩個處理超時read和write的隊列,按請求創建時間排序,如果有超時的請求出現,就放進這兩個隊列,調度算法保證超時(達到最終期限時間)的隊列中的請求會優先被處理,防止請求被餓死。由於deadline的特點,無疑在這里無法區分進程,也就不能實現針對進程的io資源控制。

 

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


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

 

從原理上看:

1、cfq是一種比較通用的調度算法,是一種以進程為出發點考慮的調度算法,保證大家盡量公平。

2、deadline是一種以提高機械硬盤吞吐量為思考出發點的調度算法,只有當有io請求達到最終期限的時候才進行調度,非常適合業務比較單一並且IO壓力比較重的業務,比如數據庫。

3、noop?思考對象如果拓展到固態硬盤,那么你就會發現,無論cfq還是deadline,都是針對機械硬盤的結構進行的隊列算法調整,而這種調整對於固態硬盤來說,完全沒有意義。對於固態硬盤來說,IO調度算法越復雜,效率就越低,因為額外要處理的邏輯越多。所以,固態硬盤這種場景下,使用noop是最好的,deadline次之,而cfq由於復雜度的原因,無疑效率最低。

 

各調度方法的原理,詳細內容可見:linux的IO調度

I/O調度方法的查看與設置

1)查看當前系統的I/O調度方法:

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

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

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了

 

參考文章:

磁盤IO過高 處理辦法

linux下io磁盤調度策略 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM