如何選擇IO排程器

廣漠飄羽發表於2020-05-08

概述

由於對multi-quque的IO排程演算法不太熟悉,為了避免誤人子弟,本文暫時只會介紹如何選擇single-queue的IO排程演算法。等將來對multi-queue有充分認識後再補充。

如果不清楚什麼是single-queuemulti-queue,可以看這文章《塊層介紹 第二篇: request層》

最新版本的Linux核心已經完全切到multi-queue架構,因此single-queue下的IO排程演算法在最新核心可能已經銷聲匿跡了。但實際上,multi-queue的IO排程演算法很大程度上參考了single-queue的IO排程演算法,因此一定程度上可以類推

單佇列排程演算法 多佇列排程演算法
deadline mq-deadline
cfq bfq
noop none
kyber

為什麼需要IO排程呢?在最開始的時候,Linux儲存在磁碟上。磁碟碟片高速旋轉,通過磁臂的移動讀取資料。磁臂的移動是物理上的機械上的移動,它無法瞬移,這速度是很慢的。如果我們讀取的資料位置很隨機,一會在A地點,一會在隔著老遠的B地點,移動的時間就全做了無用功,這也就是我們說的隨機讀寫效能慢的原因。如果讀取的資料地址是連續的,即使不是連續的也是地址接近的,那麼移動磁臂的時間損耗就少了。在最開始,IO排程的作用就是為了合併相近的IO請求,減少磁臂的移動損耗。

單佇列排程演算法

單佇列架構下,常用的排程演算法有3種:noopdeadlinecfq

noop

noop只會對請求做一些簡單的排序,其本質就是一個FIFO的佇列,只會簡單地合併臨近的IO請求後,本質還是按先來先處理的原則提交給磁碟。

根據它的原理,我們可以發現它傾向於餓死讀利於寫,為什麼呢?非同步寫是把資料直接放到page cache的,也就意味著可以通過page cache快取大量的寫資料,再一次性往下提交IO請求。而讀呢?讀一般是同步的,也就意味著必須在讀完一筆後再讀下一筆,兩次讀之間是可能被寫請求插足的。

cfq

CFQ演算法會為每個程式單獨建立一個佇列,儲存該程式產生的所有IO請求。不同佇列之間按時間片來排程,以此保證每個程式都能很好的分到I/O頻寬。這IO的時間片排程跟程式排程是非常相似的,程式排程有程式優先順序,而IO排程也有IO優先順序。

CFQ的出發點是對IO地址進行排序,以儘量少的磁碟旋轉次數來滿足儘可能多的IO請求。在CFQ演算法下,SAS盤的吞吐量大大提高了。但是相比於NOOP的缺點是,先來的IO請求並不一定能被滿足,可能會出現餓死的情況。

當一個同步佇列中的請求不足一定數量時,這個裝置可以空閒一會,即使其它佇列裡可能有請求等待處理。通常,同步請求之間在磁碟上的物理位置是連續的,所以讓磁碟稍等一會來接收更多連續的請求,這樣做可以提高吞吐量。

deadline

deadline確保請求在一個使用者可配置的時間內得到響應,避免請求餓死。其分別為讀IO和寫IO提供不同的FIFO佇列,讀FIFO佇列的最大等待時間是500ms,寫FIFO佇列的最大等待時間是5s。deadline會把提交時間相近的請求放在一批。在同一批中,請求會被排序。當一批請求達到了大小上限或著定時器超時,這批請求就會提交到裝置佇列上去。

選擇排程演算法

網上的資料基本都給出類似的結論:

  1. 對快閃記憶體等儲存介質,優先使用noop排程演算法
  2. 個人PC使用cfq排程演算法
  3. 對IO壓力比較重,且功能比較單一的場景,例如資料庫伺服器,使用deadline排程演算法

可惜的是網上的資料基本是相互複製,很少能講清楚這麼選擇的原因。

  • 為什麼快閃記憶體等介質,例如固態硬碟SSD,要選擇noop排程演算法?
    noop先來先處理的做法對磁碟來說時間損耗非常大,大量浪費了磁碟磁臂移動的時間。但是對快閃記憶體裝置,例如mmc、nand等,卻是最好的選擇,因為快閃記憶體裝置的物理結構跟磁碟完全不同,其通過一些規範的命令即可讀取資料,沒有磁臂這東西。此時IO排程演算法裡的排序、合併其實沒太大意義,反而浪費了CPU和記憶體。

  • 為什麼個人PC要用cfq排程演算法?
    在個人PC的場景上,往往需要開啟大量的程式,建立大量的程式。每個程式都可能有IO的請求。在這場景下,我們需要的是如何確保不同程式或程式組間IO資源使用的公平性。總不能因為A程式要拷貝電影,獨佔了IO資源,導致B程式無法開啟文件不是?
    cfq排程演算法是以程式之間公平享用IO資源為出發點設計的,所以,個人PC建議使用cfq排程演算法,但cfq排程演算法不僅僅用於個人PC,準確來說,cfq排程演算法適用於有大量程式的多使用者系統

  • 為什麼deadline排程演算法適用於資料庫?
    deadline是一種以提高機械硬碟吞吐量為思考出發點的排程演算法,所以準確來說,deadline排程演算法適用於IO壓力比較重,且業務功能單一的場景,而資料庫毫無疑問是最為匹配的場景了。

根據以上描述的不同排程演算法的特點,我們再根據自己的場景挑選合適的IO排程演算法就好,靈活點,自信點,不要別人說啥就選啥,別人沒說就一臉懵逼。

多佇列排程演算法

先留坑,以後填

相關文章