Linux 磁盤I/O是怎么工作的(上)

文件系統(tǒng)是對(duì)存儲(chǔ)設(shè)備上的文件,進(jìn)行組織管理的一種機(jī)制。而 Linux 在各種文件系統(tǒng)實(shí)現(xiàn)上,又抽象了一層虛擬文件系統(tǒng) VFS,它定義了一組,所有文件系統(tǒng)都支持的,數(shù)據(jù)結(jié)構(gòu)和標(biāo)準(zhǔn)接口。

這樣,對(duì)應(yīng)用程序來說,只需要跟 VFS 提供的統(tǒng)一接口交互,而不需要關(guān)注文件系統(tǒng)的具體實(shí)現(xiàn);對(duì)具體的文件系統(tǒng)來說,只需要按照 VFS 的標(biāo)準(zhǔn),就可以無縫支持各種應(yīng)用程序。

VFS 內(nèi)部又通過目錄項(xiàng)、索引節(jié)點(diǎn)、邏輯塊以及超級(jí)塊等數(shù)據(jù)結(jié)構(gòu),來管理文件。

  • 目錄項(xiàng),記錄了文件的名字,以及文件與其他目錄項(xiàng)之間的目錄關(guān)系。
  • 索引節(jié)點(diǎn),記錄了文件的元數(shù)據(jù)。
  • 邏輯塊,是由連續(xù)磁盤扇區(qū)構(gòu)成的最小讀寫單元,用來存儲(chǔ)文件數(shù)據(jù)。
  • 超級(jí)塊,用來記錄文件系統(tǒng)整體的狀態(tài),如索引節(jié)點(diǎn)和邏輯塊的使用情況等。

其中,目錄項(xiàng)是一個(gè)內(nèi)存緩存;而超級(jí)塊、索引節(jié)點(diǎn)和邏輯塊,都是存儲(chǔ)在磁盤中的持久化數(shù)據(jù)。

那么,進(jìn)一步想,磁盤又是怎么工作的呢?又有哪些指標(biāo)可以用來衡量它的性能呢?

接下來,我就帶你一起看看, Linux 磁盤 I/O 的工作原理。

磁盤

盤是可以持久化存儲(chǔ)的設(shè)備,根據(jù)存儲(chǔ)介質(zhì)的不同,常見磁盤可以分為兩類:機(jī)械磁盤和固態(tài)磁盤。

第一類,機(jī)械磁盤,也稱為硬盤驅(qū)動(dòng)器(Hard Disk Driver),通??s寫為 HDD。機(jī)械磁盤主要由盤片和讀寫磁頭組成,數(shù)據(jù)就存儲(chǔ)在盤片的環(huán)狀磁道中。在讀寫數(shù)據(jù)前,需要移動(dòng)讀寫磁頭,定位到數(shù)據(jù)所在的磁道,然后才能訪問數(shù)據(jù)。

顯然,如果 I/O 請(qǐng)求剛好連續(xù),那就不需要磁道尋址,自然可以獲得最佳性能。這其實(shí)就是我們熟悉的,連續(xù) I/O 的工作原理。與之相對(duì)應(yīng)的,當(dāng)然就是隨機(jī) I/O,它需要不停地移動(dòng)磁頭,來定位數(shù)據(jù)位置,所以讀寫速度就會(huì)比較慢。

第二類,固態(tài)磁盤(Solid State Disk),通??s寫為 SSD,由固態(tài)電子元器件組成。固態(tài)磁盤不需要磁道尋址,所以,不管是連續(xù) I/O,還是隨機(jī) I/O 的性能,都比機(jī)械磁盤要好得多。

其實(shí),無論機(jī)械磁盤,還是固態(tài)磁盤,相同磁盤的隨機(jī) I/O 都要比連續(xù) I/O 慢很多,原因也很明顯。

  • 對(duì)機(jī)械磁盤來說,我們剛剛提到過的,由于隨機(jī) I/O 需要更多的磁頭尋道和盤片旋轉(zhuǎn),它的性能自然要比連續(xù) I/O 慢。

  • 而對(duì)固態(tài)磁盤來說,雖然它的隨機(jī)性能比機(jī)械硬盤好很多,但同樣存在“先擦除再寫入”的限制。隨機(jī)讀寫會(huì)導(dǎo)致大量的垃圾回收,所以相對(duì)應(yīng)的,隨機(jī) I/O 的性能比起連續(xù) I/O 來,也還是差了很多。

  • 此外,連續(xù) I/O 還可以通過預(yù)讀的方式,來減少 I/O 請(qǐng)求的次數(shù),這也是其性能優(yōu)異的一個(gè)原因。很多性能優(yōu)化的方案,也都會(huì)從這個(gè)角度出發(fā),來優(yōu)化 I/O 性能。

此外,機(jī)械磁盤和固態(tài)磁盤還分別有一個(gè)最小的讀寫單位。

  • 機(jī)械磁盤的最小讀寫單位是扇區(qū),一般大小為 512 字節(jié)。
  • 而固態(tài)磁盤的最小讀寫單位是頁,通常大小是 4KB、8KB 等。

在上一節(jié)中,我也提到過,如果每次都讀寫 512 字節(jié)這么小的單位的話,效率很低。所以,文件系統(tǒng)會(huì)把連續(xù)的扇區(qū)或頁,組成邏輯塊,然后以邏輯塊作為最小單元來管理數(shù)據(jù)。常見的邏輯塊的大小是 4KB,也就是說,連續(xù) 8 個(gè)扇區(qū),或者單獨(dú)的一個(gè)頁,都可以組成一個(gè)邏輯塊。

除了可以按照存儲(chǔ)介質(zhì)來分類,另一個(gè)常見的分類方法,是按照接口來分類,比如可以把硬盤分為 IDE(Integrated Drive Electronics)、SCSI(Small Computer System Interface) 、SAS(Serial Attached SCSI) 、SATA(Serial ATA) 、FC(Fibre Channel) 等。

不同的接口,往往分配不同的設(shè)備名稱。比如, IDE 設(shè)備會(huì)分配一個(gè) hd 前綴的設(shè)備名,SCSI 和 SATA 設(shè)備會(huì)分配一個(gè) sd 前綴的設(shè)備名。如果是多塊同類型的磁盤,就會(huì)按照 a、b、c 等的字母順序來編號(hào)。

除了磁盤本身的分類外,當(dāng)你把磁盤接入服務(wù)器后,按照不同的使用方式,又可以把它們劃分為多種不同的架構(gòu)。

最簡(jiǎn)單的,就是直接作為獨(dú)立磁盤設(shè)備來使用。這些磁盤,往往還會(huì)根據(jù)需要,劃分為不同的邏輯分區(qū),每個(gè)分區(qū)再用數(shù)字編號(hào)。比如我們前面多次用到的 /dev/sda ,還可以分成兩個(gè)分區(qū) /dev/sda1 和 /dev/sda2。

另一個(gè)比較常用的架構(gòu),是把多塊磁盤組合成一個(gè)邏輯磁盤,構(gòu)成冗余獨(dú)立磁盤陣列,也就是 RAID(Redundant Array of Independent Disks),從而可以提高數(shù)據(jù)訪問的性能,并且增強(qiáng)數(shù)據(jù)存儲(chǔ)的可靠性。

根據(jù)容量、性能和可靠性需求的不同,RAID 一般可以劃分為多個(gè)級(jí)別,如 RAID0、RAID1、RAID5、RAID10 等。

  • RAID0 有最優(yōu)的讀寫性能,但不提供數(shù)據(jù)冗余的功能。
  • 而其他級(jí)別的 RAID,在提供數(shù)據(jù)冗余的基礎(chǔ)上,對(duì)讀寫性能也有一定程度的優(yōu)化。

最后一種架構(gòu),是把這些磁盤組合成一個(gè)網(wǎng)絡(luò)存儲(chǔ)集群,再通過 NFS、SMB、iSCSI 等網(wǎng)絡(luò)存儲(chǔ)協(xié)議,暴露給服務(wù)器使用。

其實(shí)在 Linux 中,磁盤實(shí)際上是作為一個(gè)塊設(shè)備來管理的,也就是以塊為單位讀寫數(shù)據(jù),并且支持隨機(jī)讀寫。每個(gè)塊設(shè)備都會(huì)被賦予兩個(gè)設(shè)備號(hào),分別是主、次設(shè)備號(hào)。主設(shè)備號(hào)用在驅(qū)動(dòng)程序中,用來區(qū)分設(shè)備類型;而次設(shè)備號(hào)則是用來給多個(gè)同類設(shè)備編號(hào)。

通用塊層

跟我們上一節(jié)講到的虛擬文件系統(tǒng) VFS 類似,為了減小不同塊設(shè)備的差異帶來的影響,Linux 通過一個(gè)統(tǒng)一的通用塊層,來管理各種不同的塊設(shè)備。

通用塊層,其實(shí)是處在文件系統(tǒng)和磁盤驅(qū)動(dòng)中間的一個(gè)塊設(shè)備抽象層。它主要有兩個(gè)功能 。

  • 第一個(gè)功能跟虛擬文件系統(tǒng)的功能類似。向上,為文件系統(tǒng)和應(yīng)用程序,提供訪問塊設(shè)備的標(biāo)準(zhǔn)接口;向下,把各種異構(gòu)的磁盤設(shè)備抽象為統(tǒng)一的塊設(shè)備,并提供統(tǒng)一框架來管理這些設(shè)備的驅(qū)動(dòng)程序。

  • 第二個(gè)功能,通用塊層還會(huì)給文件系統(tǒng)和應(yīng)用程序發(fā)來的 I/O 請(qǐng)求排隊(duì),并通過重新排序、請(qǐng)求合并等方式,提高磁盤讀寫的效率。

其中,對(duì) I/O 請(qǐng)求排序的過程,也就是我們熟悉的 I/O 調(diào)度。事實(shí)上,Linux 內(nèi)核支持四種 I/O 調(diào)度算法,分別是 NONE、NOOP、CFQ 以及 DeadLine。這里我也分別介紹一下。

  • 第一種 NONE ,更確切來說,并不能算 I/O 調(diào)度算法。因?yàn)樗耆皇褂萌魏?I/O 調(diào)度器,對(duì)文件系統(tǒng)和應(yīng)用程序的 I/O 其實(shí)不做任何處理,常用在虛擬機(jī)中(此時(shí)磁盤 I/O 調(diào)度完全由物理機(jī)負(fù)責(zé))

  • 第二種 NOOP ,是最簡(jiǎn)單的一種 I/O 調(diào)度算法。它實(shí)際上是一個(gè)先入先出的隊(duì)列,只做一些最基本的請(qǐng)求合并,常用于 SSD 磁盤。

  • 第三種 CFQ(Completely Fair Scheduler),也被稱為完全公平調(diào)度器,是現(xiàn)在很多發(fā)行版的默認(rèn) I/O 調(diào)度器,它為每個(gè)進(jìn)程維護(hù)了一個(gè) I/O 調(diào)度隊(duì)列,并按照時(shí)間片來均勻分布每個(gè)進(jìn)程的 I/O 請(qǐng)求

類似于進(jìn)程 CPU 調(diào)度,CFQ 還支持進(jìn)程 I/O 的優(yōu)先級(jí)調(diào)度,所以它適用于運(yùn)行大量進(jìn)程的系統(tǒng),像是桌面環(huán)境、多媒體應(yīng)用等。

最后一種 DeadLine 調(diào)度算法,分別為讀、寫請(qǐng)求創(chuàng)建了不同的 I/O 隊(duì)列,可以提高機(jī)械磁盤的吞吐量,并確保達(dá)到最終期限(deadline)的請(qǐng)求被優(yōu)先處理。DeadLine 調(diào)度算法,多用在 I/O 壓力比較重的場(chǎng)景,比如數(shù)據(jù)庫等。

I/O 棧

清楚了磁盤和通用塊層的工作原理,再結(jié)合上一期我們講過的文件系統(tǒng)原理,我們就可以整體來看 Linux 存儲(chǔ)系統(tǒng)的 I/O 原理了。

我們可以把 Linux 存儲(chǔ)系統(tǒng)的 I/O 棧,由上到下分為三個(gè)層次,分別是文件系統(tǒng)層、通用塊層和設(shè)備層。這三個(gè) I/O 層的關(guān)系如下圖所示,這其實(shí)也是 Linux 存儲(chǔ)系統(tǒng)的 I/O 棧全景圖。

根據(jù)這張 I/O 棧的全景圖,我們可以更清楚地理解,存儲(chǔ)系統(tǒng) I/O 的工作原理。

  • 文件系統(tǒng)層,包括虛擬文件系統(tǒng)和其他各種文件系統(tǒng)的具體實(shí)現(xiàn)。它為上層的應(yīng)用程序,提供標(biāo)準(zhǔn)的文件訪問接口;對(duì)下會(huì)通過通用塊層,來存儲(chǔ)和管理磁盤數(shù)據(jù)。

  • 通用塊層,包括塊設(shè)備 I/O 隊(duì)列和 I/O 調(diào)度器。它會(huì)對(duì)文件系統(tǒng)的 I/O 請(qǐng)求進(jìn)行排隊(duì),再通過重新排序和請(qǐng)求合并,然后才要發(fā)送給下一級(jí)的設(shè)備層。

  • 設(shè)備層,包括存儲(chǔ)設(shè)備和相應(yīng)的驅(qū)動(dòng)程序,負(fù)責(zé)最終物理設(shè)備的 I/O 操作。

存儲(chǔ)系統(tǒng)的 I/O ,通常是整個(gè)系統(tǒng)中最慢的一環(huán)。所以, Linux 通過多種緩存機(jī)制來優(yōu)化 I/O 效率。

比方說,為了優(yōu)化文件訪問的性能,會(huì)使用頁緩存、索引節(jié)點(diǎn)緩存、目錄項(xiàng)緩存等多種緩存機(jī)制,以減少對(duì)下層塊設(shè)備的直接調(diào)用。

同樣,為了優(yōu)化塊設(shè)備的訪問效率,會(huì)使用緩沖區(qū),來緩存塊設(shè)備的數(shù)據(jù)。

小結(jié)

在今天的文章中,我們梳理了 Linux 磁盤 I/O 的工作原理,并了解了由文件系統(tǒng)層、通用塊層和設(shè)備層構(gòu)成的 Linux 存儲(chǔ)系統(tǒng) I/O 棧。

其中,通用塊層是 Linux 磁盤 I/O 的核心。向上,它為文件系統(tǒng)和應(yīng)用程序,提供訪問了塊設(shè)備的標(biāo)準(zhǔn)接口;向下,把各種異構(gòu)的磁盤設(shè)備,抽象為統(tǒng)一的塊設(shè)備,并會(huì)對(duì)文件系統(tǒng)和應(yīng)用程序發(fā)來的 I/O 請(qǐng)求進(jìn)行重新排序、請(qǐng)求合并等,提高了磁盤訪問的效率。

原文

https://time.geekbang.org/column/article/77010

原文

https://time.geekbang.org/column/article/77010

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 磁盤又是怎么工作的呢?又有哪些指標(biāo)可以用來衡量它的性能呢? 磁盤 磁盤是可以持久化存儲(chǔ)的設(shè)備,根據(jù)存儲(chǔ)介質(zhì)的不同,...
    taj3991閱讀 764評(píng)論 0 0
  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 4,333評(píng)論 0 5
  • 從這一章開始,我們探討的話題就會(huì)與前面的話題稍有不同——我們將開始探討操作系統(tǒng)對(duì)于設(shè)備的管理以及它為用戶程序提供服...
    夏威夷的芒果閱讀 1,602評(píng)論 0 0
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 5,957評(píng)論 0 9
  • I/O基本知識(shí) 整個(gè)I/O操作由應(yīng)用程序、文件系統(tǒng)和磁盤共同完成,應(yīng)用程序?qū)/O命令發(fā)送到文件系統(tǒng),文件系統(tǒng)在合...
    修塔尋千里閱讀 1,827評(píng)論 0 4

友情鏈接更多精彩內(nèi)容