Linux磁盤I/O調度算法雜談

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

CFQ (Completely Fair Queuing 完全公平的排隊)(elevator=cfq):
這是默認算法,對於通用服務器來說通常是最好的選擇。它試圖均勻地分佈對I/O 帶寬的訪問。在多媒體應用, 總能保證audio、video 及時從磁盤讀取數據。但對於其他各類應用表現也很好。每個進程一個queue,每個queue 按照上述規則進行merge 和sort。進程之間round robin 調度,每次執行一個進程的4 個請求。

Deadline (elevator=deadline):
這個算法試圖把每次請求的延遲降至最低。該算法重排了請求的順序來提高性能。

NOOP (elevator=noop):
這個算法實現了一個簡單FIFO 隊列。他假定I/O 請求由驅動程序或者設備做了優化或者重排了順序(就像一個智能控制器完成的工作那樣)。在有些SAN 環境下,這個選擇可能是最好選擇。適用於隨機存取設備, no seek cost,非機械可隨機尋址的磁盤。

Anticipatory (elevator=as):
這個算法推遲I/O 請求,希望能對它們進行排序,獲得最高的效率。同deadline 不同之處在於每次處理完讀請求之後, 不是立即返回, 而是等待幾個微妙在這段時間內, 任何來自臨近區域的請求都被立即執行. 超時以後, 繼續原來的處理.基於下面的假設: 幾個微妙內, 程序有很大機會提交另一次請求.調度器跟蹤每個進程的io 讀寫統計信息, 以獲得最佳預期.

linux 中IO 調度方法的查看和設置的方法:
查看當前IO
cat /sys/block/{DEVICE-NAME}/queue/scheduler
cat /sys/block/sd*/queue/scheduler
例:輸出結果如下
noop anticipatory deadline [cfq]
設置當前IO
echo {SCHEDULER-NAME} > /sys/block/{DEVICE-NAME}/queue/scheduler
echo noop > /sys/block/hda/queue/scheduler

對IO 調度使用的建議:
Deadline I/O scheduler 使用輪詢的調度器,簡潔小巧,提供了最小的讀取延遲和尚佳的吞吐量,特別適合於讀取較多的環境(比如數據庫,Oracle 10G 之類).
Anticipatory I/O scheduler 假設一個塊設備只有一個物理查找磁頭(例如一個單獨的SATA 硬盤),將多個隨機的小寫入流合併成一個大寫入流,用寫入延時換取最大的寫入吞吐量.適用於大多數環境,特別是寫入較多的環境(比如文件服務 器)Web,App 等應用我們可以採納as 調度.
CFQ I/O scheduler 使用QoS 策略爲所有任務分配等量的帶寬,避免進程被餓死並實現了較低的延遲,可以認爲是上述兩種調度器的折中.適用於有大量進程的多用戶系統,我在生產環境中測試 過一臺機器本來流量只有350M 的樣子,有時壓力就不行了,流量也上不去了,因爲讀比較多,所以使用deadline 後,流量上升了50M,從流量之類的圖上也見到穩定很多.

linux 啓動時設置默認IO 調度
讓系統啓動時就使用默認的IO 方法,只需在grub.conf 文件中加入類似如下行
kernel /vmlinuz-2.6.24 ro root=/dev/sda1 elevator=deadline
有關IO 的幾個內核參數
/proc/sys/vm/dirty_ratio
這個參數控制文件系統的文件系統寫緩衝區的大小,單位是百分比,表示系統內存的百分比,表示當寫緩衝使用到系統內存多少的時候,開始向磁盤寫出數據。增大 之會使用更多系統內存用於磁盤寫緩衝,也可以極大提高系統的寫性能。但是,當你需要持續、恆定的寫入場合時,應該降低其數值,一般啓動上缺省是10。下面 是增大的方法:
echo ‘40′> /proc/sys/vm/dirty_ratio
/proc/sys/vm/dirty_background_ratio
這個參數控制文件系統的pdflush 進程,在何時刷新磁盤。單位是百分比,表示系統內存的百分比,意思是當寫緩衝使用到系統內存多少的時候, pdflush 開始向磁盤寫出數據。增大之會使用更多系統內存用於磁盤寫緩衝,也可以極大提高系統的寫性能。但是,當你需要持續、恆定的寫入場合時,應該降低其數值,一 般啓動上缺省是5。下面是增大的方法:
echo ‘20′ > /proc/sys/vm/dirty_background_ratio
/proc/sys/vm/dirty_writeback_centisecs
這個參數控制內核的髒數據刷新進程pdflush 的運行間隔。單位是1/100 秒。缺省數值是500,也就是5 秒。如果你的系統是持續地寫入動作,那麼實際上還是降低這個數值比較好,這樣可以把尖峯的寫操作削平成多次寫操作。設置方法如下:
echo ‘200′ > /proc/sys/vm/dirty_writeback_centisecs
如果你的系統是短期地尖峯式的寫操作,並且寫入數據不大(幾十M/次)且內存有比較多富裕,那麼應該增大此數值:
echo ‘1000′ > /proc/sys/vm/dirty_writeback_centisecs
/proc/sys/vm/dirty_expire_centisecs
這個參數聲明Linux 內核寫緩衝區裏面的數據多“舊”了之後,pdflush 進程就開始考慮寫到磁盤中去。單位是1/100 秒。缺省是30000,也就是30 秒的數據就算舊了,將會刷新磁盤。對於特別重載的寫操作來說,這個值適當縮小也是好的,但也不能縮小太多,因爲縮小太多也會導致IO 提高太快。建議設置爲1500,也就是15 秒算舊。
echo ‘1500′ > /proc/sys/vm/dirty_expire_centisecs
當然,如果你的系統內存比較大,並且寫入模式是間歇式的,並且每次寫入的數據不大(比如幾十M),那麼這個值還是大些的好。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章