1. 程式人生 > 其它 >24-基礎篇:Linux磁碟I/O是怎麼工作的(上)

24-基礎篇:Linux磁碟I/O是怎麼工作的(上)





磁碟

按照儲存介質分類:機械磁碟和固態磁碟

  1. 機械磁碟,也稱為硬碟驅動器,通常縮寫為HDD
    機械磁碟主要由碟片和讀寫磁頭組成,資料就儲存在碟片的環狀磁軌中
    在讀寫資料前,需要移動讀寫磁頭,定位到資料所在的磁軌,然後才能訪問資料

    連續I/O,請求剛好連續,那就不需要磁軌定址,可以獲得最佳效能

    隨機I/O,它需要不停地移動磁頭,來定位資料位置,所以讀寫速度就會比較慢

  2. 固態磁碟,通常縮寫為SSD,由固態電子元器件組成
    固態磁碟不需要磁軌定址,所以不管是連續I/O,還是隨機I/O的效能,都比機械磁碟要好得多


其實,無論機械磁碟,還是固態磁碟,相同磁碟的隨機I/O都要比連續I/O慢很多,原因也很明顯

  1. 對機械磁碟來說,由於隨機I/O需要更多的磁頭尋道和碟片旋轉,它的效能自然要比連續I/O慢
  2. 對固態磁碟來說,雖然它的隨機效能比機械硬碟好很多,但同樣存在“先擦除再寫入”的限制
    隨機讀寫會導致大量的垃圾回收,所以相對應的,隨機I/O的效能比起連續I/O來,也還是差了很多
    連續I/O還可以通過預讀的方式,來減少I/O請求的次數,這也是其效能優異的一個原因
    很多效能優化的方案,也都會從這個角度出發,來優化I/O效能

此外,機械磁碟和固態磁碟還分別有一個最小的讀寫單位

  1. 機械磁碟的最小讀寫單位是扇區,一般大小為512位元組
  2. 固態磁碟的最小讀寫單位是頁,通常大小是4KB、8KB等

按照介面分類:

可以把硬碟分為IDE、SCSI 、SAS、SATA 、FC等

不同的介面,往往分配不同的裝置名稱
比如, IDE裝置會分配一個hd字首的裝置名
SCSI和SATA裝置會分配一個sd字首的裝置名
如果是多塊同類型的磁碟,就會按照a、b、c等的字母順序來編號


按照使用方式劃分為多種不同的架構:

  1. 直接作為獨立磁碟裝置來使用。
    這些磁碟,往往還會根據需要,劃分為不同的邏輯分割槽,每個分割槽再用數字編號
    例如/dev/sda,還可以分成兩個分割槽/dev/sda1和/dev/sda2
  2. RAID冗餘獨立磁碟陣列。
    可以提高資料訪問的效能,並且增強資料儲存的可靠性
    根據容量、效能和可靠性需求的不同
    RAID一般可以劃分為多個級別,如RAID0、RAID1、RAID5、RAID10等
    1. RAID0有最優的讀寫效能,但不提供資料冗餘的功能
    2. 其他級別的RAID,在提供資料冗餘的基礎上,對讀寫效能也有一定程度的優化
  3. 磁碟組合成一個網路儲存叢集。
    通過 NFS、SMB、iSCSI 等網 絡儲存協議,暴露給伺服器使用

在Linux中,磁碟實際上是作為一個塊裝置來管理的,也就是以塊為單位讀寫資料,並且支援隨機讀寫
每個塊裝置都會被賦予兩個裝置號,分別是主、次裝置號
主裝置號用在驅動程式中,用來區分裝置型別
而次裝置號則是用來給多個同類裝置編號



通用塊層

跟虛擬檔案系統VFS類似,為了減小不同塊裝置的差異帶來的影響,Linux通過一個統一的通用塊層,來管理各種不同的塊裝置

通用塊層,其實是處在檔案系統和磁碟驅動中間的一個塊裝置抽象層
它主要有兩個功能:

  1. 第一個功能跟虛擬檔案系統的功能類似
    向上,為檔案系統和應用程式,提供訪問塊裝置的標準介面
    向下,把各種異構的磁碟裝置抽象為統一的塊裝置,並提供統一框架來管理這些裝置的驅動程式
  2. 第二個功能,通用塊層還會給檔案系統和應用程式發來的I/O請求排隊
    並通過重新排序、請求合併等方式,提高磁碟讀寫的效率

其中,對I/O請求排序的過程,就是I/O排程,事實上,Linux核心支援四種I/O排程演算法

  1. NONE更確切來說,並不能算I/O排程演算法
    因為它完全不使用任何I/O排程器,對檔案系統和應用程式的I/O其實不做任何處理,常用在虛擬機器中(此時磁碟I/O排程完全由物理機負責)
  2. NOOP 是最簡單的一種I/O排程演算法
    它實際上是一個先入先出的佇列,只做一些最基本的請求合併,常用於SSD磁碟
  3. CFQ也被稱為完全公平排程器
    是現在很多發行版的預設I/O排程器,它為每個程序維護了一個I/O排程佇列
    並按照時間片來均勻分佈每個程序的I/O請求
    類似於程序CPU排程,CFQ還支援程序I/O的優先順序排程,
    所以它適用於執行大量程序的系統,像是桌面環境、多媒體應用等
  4. DeadLine排程演算法
    分別為讀、寫請求建立了不同的I/O佇列,可以提高機械磁碟的吞吐量,並確保達到最終期限的請求被優先處理
    DeadLine排程演算法,多用在I/O壓力比較重的場景,比如資料庫等


I/O棧

可以把Linux儲存系統的I/O棧,由上到下分為三個層次
分別是檔案系統層、通用塊層和裝置層
這三個I/O層的關係如下圖所示,這其實也是Linux儲存系統的I/O棧全景圖

根據這張I/O棧的全景圖,可以更清楚地理解儲存系統I/O的工作原理

  1. 檔案系統層,包括虛擬檔案系統和其他各種檔案系統的具體實現
    它為上層的應用程式,提供標準的檔案訪問介面
    對下會通過通用塊層,來儲存和管理磁碟資料
  2. 通用塊層,包括塊裝置I/O佇列和I/O排程器
    它會對檔案系統的I/O請求進行排隊, 再通過重新排序和請求合併,然後才要傳送給下一級的裝置層
  3. 裝置層,包括儲存裝置和相應的驅動程式,負責最終物理裝置的I/O操作

儲存系統的I/O ,通常是整個系統中最慢的一環。所以,Linux通過多種快取機制來優化I/O效率

比方說,為了優化檔案訪問的效能,會使用頁快取、索引節點快取、目錄項快取等多種快取機制,以減少對下層塊裝置的直接呼叫

同樣,為了優化塊裝置的訪問效率,會使用緩衝區,來快取塊裝置的資料



小結

由檔案系統層、通用塊層和裝置層構成的Linux儲存系統I/O棧

通用塊層是Linux磁碟I/O的核心,向上,它為檔案系統和應用程式,提供訪問了塊裝置的標準介面
向下,把各種異構的磁碟裝置,抽象為統一的塊裝置
並會對檔案系統和應用程式發來的I/O請求進行重新排序、請求合併等,提高了磁碟訪問的效率


轉載請註明出處喲~ https://www.cnblogs.com/lichengguo