在“系統(tǒng)存儲”專題中,我們將按照“從上至下”的順序向讀者介紹整個“系統(tǒng)存儲”體系。在這個專題中我們將至少介紹機械硬盤的主要結構、磁盤陣列的分類、操作系統(tǒng)的EXT文件系統(tǒng)、NAS文件共享存儲方案、分布式文件系統(tǒng)重要技術點和分布式文件系統(tǒng)示例。最后如果有時間我們將自行設計一款分布式文件系統(tǒng)。下圖可以大致描述筆者的寫作思路:
本專題首先會花費幾篇文章向讀者介紹塊存儲的知識,包括最底層機械硬盤、固態(tài)硬盤的構造結構和工作過程。塊存儲的知識中我們還將介紹磁盤陣列技術,包括磁盤陣列的組織方式和設備類型。最后塊存儲知識中我們介紹操作系統(tǒng)中的文件系統(tǒng),包括EXT系列文件系統(tǒng)和XFS文件系統(tǒng)(會順帶提到Windows操作系統(tǒng)使用的NTFS文件系統(tǒng))。接下來的幾篇文章我們會介紹搭建在塊存儲方案上的關系型數(shù)據(jù)庫,文章會主要講解Mysql數(shù)據(jù)庫,包括MySQL數(shù)據(jù)庫中最常被使用的InnerDB存儲引擎、索引構造方式以及MySQL數(shù)據(jù)庫集群的幾種構造方式。
由于在《標準Web系統(tǒng)的架構分層》這篇文章中,筆者已經大致說明了系統(tǒng)存儲專題的寫作過程,所以本文就直接開始塊存儲技術的介紹了。筆者計劃花費兩到三篇文章的篇幅,向大家介紹塊存儲技術的主要知識點。
塊存儲技術的構成基礎是最下層的硬件存儲設備,這些硬件存儲設備可能是機械硬盤也可能是固態(tài)硬盤。一個操作系統(tǒng)下可以獨立控制多個硬件存儲設備,但是這些硬件存儲設備的工作相對獨立,通過Centos操作系統(tǒng)的df命令看到的也是幾個獨立的設備文件。通過陣列控制層的設備可以在同一個操作系統(tǒng)下協(xié)同控制多個存儲設備,讓后者在操作系統(tǒng)層被視為同一個存儲設備。
操作系統(tǒng)控制多個獨立的存儲設備。下圖表示的三個硬盤設備在操作系統(tǒng)下獨立工作,在操作系統(tǒng)下顯示了三個設備文件:
操作系統(tǒng)通過陣列控制設備控制多個存儲設備。陣列控制設備在市場上從低端到高端有很多選擇。目前市場上的一些主板就自己集成了陣列控制芯片,如果中小企業(yè)需要硬盤陣列設備可以購買民用級產品,市場價格普遍在幾千塊左右。高端設備可以購買IBM/EMC提供的商業(yè)級/工業(yè)級設備,市場價格從幾萬到幾千萬不等。筆者將在本專題中詳細介紹硬盤陣列的重要技術知識點。
為什么操作系統(tǒng)層可以做到以上兩種存儲設備的組織方案同時兼容呢?因為操作系統(tǒng)層通過各種文件系統(tǒng)規(guī)則,可以過濾掉各種存儲設備的不同硬件特性。EXT1、EXT2、EXT3、EXT4系列文件系統(tǒng)和XFS文件系統(tǒng)都是Linux操作系統(tǒng)下常用的文件系統(tǒng),Btrfs文件系統(tǒng)是最近今年Linux操作系統(tǒng)下越來越流行的新一代操作系統(tǒng)。這些文件系統(tǒng)的共同特點是:通過文件系統(tǒng)內部能夠辨識的一個文件索引結構規(guī)范對下層的硬件設備結構進行封裝,以便起到屏蔽和代理操作下層硬件結構的目的。 那么當下層存儲設備不是機械硬盤而是固態(tài)硬盤又或者是陣列控制設備時,又是怎樣的工作原理呢?本專題中將會一一解答這些問題。對于操作系統(tǒng)中的文件系統(tǒng),我們將著重介紹EXT系列文件系統(tǒng)的結構。
3-1、機械硬盤結構
現(xiàn)在的機械硬盤技術都非常成熟了,存儲容量也出現(xiàn)了幾何級增長。但是機械硬盤的基本結構卻一直沒有太大的變化:它基本上是由機械臂(磁頭臂)、主軸、多個成對的磁頭和磁面構成。在每個磁面上被分成多個磁道、多個扇面和多個扇區(qū),它們的具體存在形式如下:
磁面上會有多個磁道,它們在一個磁面上擁有不同的磁道編號。從磁面最外圍離主軸最遠的磁道到磁面最內側離主軸最近的磁道,它們的編號從0開始,分別是0、1、2、3、4…….N(N大于等于10000,依據(jù)硬盤制作工藝不同而不同)。磁頭將會順著磁道基于磁面的轉動讀取數(shù)據(jù),并且可以在各個磁道間切換位置。
實際情況下,外部將要存儲到硬盤上的數(shù)據(jù)不會一次性寫滿整個磁道,讀取數(shù)據(jù)到外部時也不需要讀取整個磁道的數(shù)據(jù)。這是因為一個磁道被分為多個弧段,這些弧段稱之為扇區(qū)。扇區(qū)是硬盤上存儲數(shù)據(jù)的最基本物理單元。注意,目前市場上無論哪個供應商提供的機械硬盤產品,每個物理扇區(qū)單元固定的存儲容量都是512字節(jié)。只是根據(jù)硬盤密度不一樣,單位磁面下的扇區(qū)數(shù)量也不一樣。既然扇區(qū)是數(shù)據(jù)存儲的基本單元,就意味著一次硬盤讀寫操作的最小數(shù)據(jù)量就是512字節(jié)。
那么問題來了,是不是覺得512字節(jié)太小了點?是的,很多時候操作系統(tǒng)層面請求讀寫操作的文件都會大于一個扇區(qū)的單位容量。那么在物理層面上就需要兩個甚至更多個扇區(qū)來存儲這個文件,那么怎樣來規(guī)劃存儲一個文件的若干扇區(qū)在磁面上的分布,從而達到減少讀取時間的目的呢?
操作系統(tǒng)層面會將物理硬盤上兩個或者多個能夠連續(xù)讀取的扇區(qū)組成合并成一個區(qū)域,稱之為“簇”。注意,這兩個或者多個能夠連續(xù)讀取的扇區(qū)不一定在物理上是連續(xù)的。這是什么原因呢?這是因為硬盤轉動的速度很快(標準速度為7200轉/分),當磁頭完成一個“扇區(qū)1”的讀寫后還來不及讀取下一個連續(xù)的“扇區(qū)2”相鄰的扇區(qū)就“飛”過去了,要等磁面再轉動一圈到預定“扇區(qū)2”的位置才能繼續(xù)進行讀寫。
所以一個簇在物理磁面的分布可能是不連續(xù)的。實際上各個硬盤生產商都會設置一個“跳躍因子”來確定能夠連續(xù)讀取的扇區(qū)。如下圖所示,四個不存在于連續(xù)物理位置的扇區(qū)構成一個簇。這樣保證了磁面在旋轉一圈的情況下就可以完成一個簇的全部讀寫。
最后說明一點,雖然扇面是硬件層面上機械磁盤讀取數(shù)據(jù)的最小單元,但是“簇”才是操作系統(tǒng)層面上讀取磁盤數(shù)據(jù)的最小單元。我們后文將講解EXT文件系統(tǒng)和Btrfs文件系統(tǒng),這兩種文件系統(tǒng)定義的簇大小是不一樣的。例如EXT文件系統(tǒng)的族大小可以有1KB(兩個扇區(qū))、2KB(四個扇區(qū))、4KB(八個扇區(qū))等多種選擇。那么如果一個文件太小,不需要用完一個簇怎么辦呢?沒辦法,它有需要使用至少一個簇的硬盤空間。也就是說,在操作系統(tǒng)存儲一個文件時,即使一個簇沒有占滿,剩下的簇空間也不能再使用了。這就是為什么一個文件在操作系統(tǒng)上有兩個大?。阂粋€是文件的實際大小、另一個是文件占用硬盤空間的大小。
3-2、機械硬盤性能瓶頸
3-2-1、影響機械硬盤性能的因素
當需要從硬盤上讀取一個文件是,首先會要求磁頭定位到這個文件的起始扇區(qū)。這個定位過程包括兩個步驟:一個是磁頭定位到對應的磁道,然后等待主軸馬達帶動盤片轉動到正確的位置,這個過程所花費的時間被稱為尋址時間。也就是說尋址時間實際上包含兩部分:磁頭定位到磁道的時間為尋道時間,等待盤片轉動到正確位置的時間稱為旋轉等待時間。
硬盤尋址的目的是為了找到將要讀取的文件的起始扇區(qū),并開始去取數(shù)據(jù)。這就可以解釋為什么硬盤上讀取一個100MB大小的文件和讀取1000個100KB大小的文件時間是完全不一樣的現(xiàn)象了:通常來說一個100MB的文件是存儲在硬盤上可以連續(xù)讀取的扇區(qū)上的,也就是說當硬盤需要讀取這個文件時只需要進行一次尋址(為什么說是“通常”呢?因為前提是硬盤上至少要有一端連續(xù)空白的扇區(qū),如果此時硬盤上碎片太多可能就找不到這樣的連續(xù)空白區(qū)域了);而讀取1000個文件時,由于這些文件的起始存儲位不連續(xù),所以每次都要進行尋址操作。尋址時間是評價機械硬盤性能的重要指標,這個指標和硬盤轉數(shù)、磁頭數(shù)有直接關系:
硬盤轉速越快的硬盤,在同樣的尋址算法控制條件下將能夠更快的將正確的扇區(qū)轉動到磁頭下方。但是硬盤轉速也不能做得無限快,因為硬盤轉速越快要求的磁面工藝、主馬達工藝也就越高,并且產生的噪音、溫度也會成幾何級增加?,F(xiàn)在民用級、商用級和工業(yè)級硬盤上最常采用三種轉速選擇:5400轉/分、7200轉/分和10000轉/分。
磁頭數(shù),現(xiàn)在的機械硬盤中一般都包含了多個盤片并且分別使用獨立的磁頭。這樣做的主要作用是在硬盤密度不變的情況下增加機械硬盤的容量。實際上這樣的做法也可以增加一定的硬盤性能,因為讀取存儲在不同磁面上的文件時,它們的尋道時間可以相對獨立。但是其對性能的提示只能是有限的,因為這些盤片共享同一個主軸馬達。
機械硬盤的工作原理導致了它的工作性能會遠遜于內存,現(xiàn)在主流的7200轉硬盤外部傳輸速度的理論峰值大概也就是200MB/s。那么問題又來了,天才的硬件工程師難道就沒有辦法增加機械硬盤讀寫性能了嗎?
答案是否定的,硬件工程師為機械硬盤集成了緩存,并采用預讀機制讀取當前扇區(qū)的臨近扇區(qū)。舉個例子,當硬盤讀取一個文件所在扇區(qū)時,會將這個扇區(qū)臨近的若干扇區(qū)上的數(shù)據(jù)一同讀取出來并存儲到硬盤緩存中。這樣做的原因是依據(jù)計算機科學中得一個著名原理:局部性原理。
局部性原理包括三層含義。時間局部性,如果一個信息項正在被訪問,那么在近期它很可能被再次訪問??臻g局部性,在近期將要被使用的信息很可能與現(xiàn)在正在使用的信息在空間地址上是臨近的。順序局部性,在典型程序中,除轉移類指令外,大部分指令是順序進行的。局部性是所有高速緩存設計的基本原理依據(jù)。
說人話,局部性原理在硬盤硬件設備設計中被應用的依據(jù)是:當一個文件被讀取時,在它臨近扇區(qū)所存儲的文件數(shù)據(jù)也將在近期被讀取。所以硬盤會預先讀取后者到緩存中,以便在不久的將來,這些數(shù)據(jù)被請求讀取時直接從緩存中向外部設備輸出文件數(shù)據(jù)。
局部性原理不止適合高速緩存這樣的硬件設計,它也適用于軟件設計:一個程序90%的時間運行在10%的代碼上。
3-2-2、順序讀寫和隨機讀寫
上一小節(jié)已經提到硬盤的順序讀寫和隨機讀寫有非常大的性能差異,其中主要的原因是兩者尋址操作上所耗費的時間存在巨大差異。那么順序讀寫和隨機讀寫的差異到底有多大呢?僅僅是靠上一小節(jié)的文字描述顯然不能給讀者數(shù)值化的認識,所以在本小節(jié)中我們將使用一款名叫CrystalDiskMark的測試軟件,讓讀者具體體會一下兩者的巨大區(qū)別:
以上是筆者編寫文稿使用的某品牌筆記本上5400轉機械硬盤的測試截圖(題外話,這款筆記本用起來真想罵人),這個機械硬盤屬于中低端硬盤,但是相同級別的硬盤在萬元級以下的筆記本上卻被大量使用,所以這個測試結果很能說明一些問題。首先解釋一下以上截圖中的幾個主要項目:
從上圖的測試結果來看,順序讀寫的性能遠遠高于隨機讀寫的性能,使用了IO隊列的讀性能又遠遠高于沒有使用IO隊列的讀性能(且寫性能基本持平)。當然以上的測試數(shù)值和選用的機械硬盤型號是密切相關的,但無論數(shù)值結果如何變化,最后都會符合以上所描述的性能規(guī)則。
例如如果您對7200轉企業(yè)級硬盤進行測試,那么所有測試項的橫向數(shù)值會高出很多;如果您的INTEL SSD 企業(yè)級固態(tài)硬盤卡進行測試,那么橫向數(shù)值又會再高出很多倍。下圖展示了INTEL SSD 750 企業(yè)級固態(tài)硬盤卡的測試結果(截圖來源于網(wǎng)絡):
看了以上來源于網(wǎng)絡的截圖后,是不是感覺整個世界瞬間清爽了。目前固態(tài)硬盤的生產工藝日趨成熟,單位容量價格也趨于下降通道。固態(tài)硬盤替代機械硬盤是一個必然趨勢,遲早有一天后者將被完全替換。本節(jié)向讀者介紹固態(tài)硬盤大致的構成結構和工作過程。
4-1、固態(tài)硬盤結構
固態(tài)硬盤的結構和工作原理和機械硬盤大不一樣。它主要由大量NAND Flash顆粒、Flash存儲芯片、SSD控制器控制芯片構成。他們三者的關系通過下圖進行表示:
在一個固態(tài)硬盤上會有若干Flash存儲芯片(可能有2顆、4顆、8顆等數(shù)值),每顆存儲芯片內部包含大量NAND Flash顆粒,目前(2016年)NAND Flash顆粒的制作工藝已經達到12nm(2012年的主流工藝是90nm)。無論NAND Flash顆粒的制作工藝如何,每一個單位的存儲容量都是512字節(jié)。多個Flash存儲芯片被一個SSD主控芯片,目前能夠生成SSD主控芯片的廠商不多,例如:SandForce、Marvell、三星、JMicron、Intel等。SSD主控芯片的主要工作包括識別來自于外部接口(PCI-E、SATA等)的控制指令、在將數(shù)據(jù)寫入Flash存儲芯片前接收和壓縮這些數(shù)據(jù)、在將數(shù)據(jù)送入內存前解壓從Flash存儲芯片讀取的數(shù)據(jù)、完成 LBA和PBA的映射轉換(這個過程將在下一小節(jié)進行介紹)等工作。
雖然一個單位的NAND Flash顆粒存儲容量是512字節(jié),但是SSD主控芯片進行數(shù)據(jù)操作的最小單位并不是512字節(jié)。在SSD操作規(guī)則中定義的一個數(shù)據(jù)操作的最小單位為4KB,它包括了8個單位的NAND Flash顆粒稱為Flash Page(有的資料中稱為Host Page)。如果將固態(tài)硬盤和機械硬盤進行對比,那么機械硬盤中的一個最小的操作單位就是扇區(qū),單位大小就是512字節(jié);固態(tài)硬盤中的一個最小操作單位就是Flash Page,單位大小為4K。這就解釋了上文中提到的硬盤讀寫性能測試中,為什么測試軟件會專門針對4K大小的文件進行讀寫測試了。
既然固態(tài)硬盤中最小的操作單位為4K,那么在進行操作系統(tǒng)文件系統(tǒng)格式化的時候就需要注意了。文件系統(tǒng)中設置的一個簇大小不能小于4K且最好為4K的整數(shù)倍,這樣才能保證充分發(fā)揮固態(tài)硬盤的性能。
固態(tài)硬盤不依靠磁頭定位和主馬達旋轉確定數(shù)據(jù)的物理位置,所以固態(tài)硬盤沒有尋址時間。SSD控制芯片擁有的多個控制通道可以讓它同時向多個Flash存儲芯片發(fā)送讀寫指令,這類似于機械磁盤上可以獨立工作的磁頭臂,但卻沒有共享主軸馬達的限制。這些特點足以保證固態(tài)硬盤的性能遠遠高于機械硬盤。這也讓我們認識到,以下因素影響著固態(tài)硬盤的最終性能:
SSD主控芯片:上文已經說到SSD主控芯片幾乎完成了固態(tài)硬盤上所涉及的所有控制指令操作和數(shù)據(jù)讀寫操作。不同的SSD主控芯片內置的FTL算法不一樣、數(shù)據(jù)壓縮/解壓算法不一樣、控制通道數(shù)也不一樣,所以固態(tài)硬盤采用哪種SSD主控芯片將直接影響其性能,目前最好的控制芯片來自于Intel,最廣泛使用的控制芯片來自于三星。
FLash存儲芯片工藝:本文提到的NAND Flash顆粒只是其中一種使用最廣泛的型號,實際上還有NOR Flash顆粒等。NAND Flash顆粒又分為兩種子類型:MLC存儲顆粒與SLC存儲顆粒。在相同單位體積下,MLC可以提供兩倍于SLC的存儲空間,而后者在存儲響應時間和存儲穩(wěn)定性上又高于前者。所以MLC存儲顆粒市場占有率更高,SLC存儲顆粒更傾向于企業(yè)級市場。
本小節(jié)我們要解決一個關鍵問題:既然機械硬盤和固態(tài)硬盤從工作原理、制作工藝、技術規(guī)范等多個方面都完全不一樣,那為什么無論硬件層是使用機械硬盤還是固態(tài)硬盤操作系統(tǒng)卻都可以進行識別,并在其上進行數(shù)據(jù)讀寫呢?
這個問題中,計算機系統(tǒng)不同層次對數(shù)據(jù)操作最小單位的定義不一致都還是一個小問題:雖然機械硬盤上數(shù)據(jù)操作單元為512字節(jié)、固態(tài)硬盤上數(shù)據(jù)操作單元為4KB、操作系統(tǒng)層面定義的數(shù)據(jù)操作單元可能是1KB\2KB\4KB\8KB等等。但是只要這些層次上的文件起始地址都是固定的,則各層的地址對應關系就可以找到的。也就是說操作系統(tǒng)上的地址X可以映射到機械硬盤的地址Y又或者映射到固態(tài)硬盤的地址Z,只不過存儲小文件時的真實可用空間可能產生誤差。
但是這里有一個固態(tài)硬盤上的操作規(guī)則會引起比較大的問題,這就是固態(tài)硬盤對數(shù)據(jù)的刪除操作:固態(tài)硬盤在進行數(shù)據(jù)刪除時是按照“塊”單位進行的,一個“塊”包含128個或者256個Flash Page。當進行刪除操作時,SSD主控芯片會首先將這個塊中還“有效”的數(shù)據(jù)移動到屬于其它“塊”的另一些Flash Page中,然后再進行“無效”數(shù)據(jù)的清理。也就是說以前操作系統(tǒng)通過地址X的可以讀取的文件數(shù)據(jù),現(xiàn)在通過地址X就可能讀取不到了。那么這些固態(tài)硬盤的底層操作過程對于操作系統(tǒng)來說應該是完全透明的,否則操作系統(tǒng)就不能將固態(tài)硬盤當成機械硬盤進行操作。
這就是說,對于操作系統(tǒng)來說以前使用地址X進行存儲的文件,無論什么是否都能夠再通過地址X讀取到。這里提到了兩種地址:一種是操作系統(tǒng)讀寫文件的地址——稱為邏輯地址;另一種是固態(tài)硬盤進行文件操作的真實地址——稱為物理地址。
FTL(Flash translation layer)閃存地址轉換是SSD固態(tài)硬盤控制芯片需要負責的主要工作之一,F(xiàn)TL的主要作用就是記錄物理地址和邏輯地址的轉換關系,F(xiàn)TL的核心是一張物理地址和邏輯地址的映射表,這張映射表存儲在固態(tài)硬盤一個專門的SRAM/DRAM芯片上或者若干獨立的NAND Flash Page 上。正是SSD固態(tài)硬盤的控制芯片有這樣一個轉換過程,操作系統(tǒng)才能將固態(tài)硬盤當做機械硬盤進行操作,并且SSD固態(tài)硬盤主控制芯片上FTL算法的性能直接影響著整個SSD固態(tài)硬盤的性能。請看下圖的FTL轉換示例:
操作系統(tǒng)對磁盤讀寫操作的最小單位為“簇”(EXT文件系統(tǒng)稱為block size)。以NTFS文件系統(tǒng)為例,默認的“簇”大小為4K(當然您可以選擇更大的“簇”大小,這樣會浪費更多的存儲空間,但是可以加快讀寫性能)。即使一個文件的大小不到4K,也會占用一個“簇”的大小。如果一個文件為210KB,那么理論上就需要占用53個“簇”空間(4KB),或者需要占用105個“簇”空間(2KB)。
當一個210KB大小文件的寫請求從操作系統(tǒng)層傳來時,都以邏輯地址進行描述。當SSD固態(tài)硬盤主控芯片收到這個文件的寫請求時,會到FTL映射表中尋找53個空閑的Flash Page來存儲這些數(shù)據(jù),并將物理位置和邏輯位置的映射關系記錄到FTL映射表中;當一個210KB大小文件的讀請求從操作系統(tǒng)傳來時,SSD固態(tài)硬盤控制芯片會首先在FTL映射表中尋找邏輯為止對應的若干物理位置,以便知曉到固態(tài)硬盤的哪些Flash Page去讀取數(shù)據(jù)。
還需要注意,在進行數(shù)據(jù)寫操作時,如果沒有尋找到足夠的空閑的Flash Page位置那么有兩種可能:第一種可能是,在SSD固態(tài)硬盤上確實已經沒有210KB的空間了,這時操作系統(tǒng)就會收到磁盤空間已滿的信息;另一種情況是有部分空間被“無效”數(shù)據(jù)占用(這些“無效”數(shù)據(jù)來是前被操作系統(tǒng)刪除的數(shù)據(jù)),這時固態(tài)硬盤就要進行無效數(shù)據(jù)清理。SSD固態(tài)硬盤的數(shù)據(jù)清理是將若干Flash Page的區(qū)域全部清理,稱為塊。清理操作過程已經在上文中大致介紹過。這也是為什么固體硬盤在使用一段時間后(特別是存儲空間被占用滿后),固態(tài)硬盤的性能會出現(xiàn)明顯下降的原因。
最后需要注意,實際上由操作系統(tǒng)傳來的數(shù)據(jù)和操作請求也不是直接就發(fā)送到SSD主控芯片了,而是需要經過軟件和硬件的多層傳遞。在硬件層面上來說,數(shù)據(jù)一般需要通過主板上的南橋芯片(在經過磁盤陣列控制芯片)才能傳送到SSD固態(tài)硬盤的外部接口(例如SATA3.0、USB3.0等),最后再達SSD主控芯片。
單塊硬盤進行數(shù)據(jù)存儲可能會存在以下問題:
硬盤容量有限制,當容量不足時不能進行硬件擴容。現(xiàn)在磁盤技術在磁盤容量上已經有了長足的發(fā)展,目前(2016)機械硬盤的主流容量已經達到6TB,固態(tài)硬盤的主流容量也達到512GB。但是單塊硬盤始終都存在較嚴重的容量擴充問題,除非讀者在擴容時手動遷移數(shù)據(jù)。
數(shù)據(jù)可靠性性問題。單塊硬盤不存在任何備份機制,雖然現(xiàn)在有很多扇區(qū)檢測軟件可以幫助開發(fā)人員/運維人員提前發(fā)現(xiàn)硬盤損壞的磁道,但是都不能保證99.99%的運行可靠性。一旦硬盤由于各種原因損壞(電壓不穩(wěn)、磁頭位移等),存儲在其上的數(shù)據(jù)就可能永久丟失。
讀寫性能瓶頸。這個問題在SSD固態(tài)硬盤上還不太明顯,目前主流的固態(tài)硬盤的外部傳輸速度可達到550MB/S,這個速度基本上達到了SATA 3/USB 3.0接口規(guī)范的理論峰值。但這個問題對于機械硬盤來說卻很明顯了,由于機械硬盤的讀寫性能受到磁頭數(shù)量、盤片轉速、盤片工藝等因素的影響,所以機械硬盤的讀寫性能一直沒有一個質的飛躍。如果將單個硬盤應用在生產系統(tǒng)上,那么磁盤讀寫性能無疑將會整個系統(tǒng)的性能瓶頸。另外SATA 3結構理論6Gbps的傳輸帶寬必要時也需要找到替代方案。
為了解決以上這些問題,硬件工程師將多個硬盤按照不同的規(guī)則組合在一起形成各種集群化的數(shù)據(jù)存儲結構,這些存儲結構被稱為磁盤陣列(Redundant Arrays of Independent Disks,RAID)。磁盤陣列解決以上這些問題的基本思路有:
通過硬盤橫向擴展或者縱向擴展的方式,解決整個磁盤整理存儲容量限制的問題。而對于上層操作系統(tǒng)來說,看到的都只是一個磁盤設備文件/操作盤符而已。
通過數(shù)據(jù)鏡像或者數(shù)據(jù)校驗的方式解決數(shù)據(jù)冗余和數(shù)據(jù)恢復的問題。
通過陣列控制芯片分發(fā)數(shù)據(jù)讀寫請求的方式,將原本集中在一塊硬盤上的數(shù)據(jù)讀寫請求分散到多塊硬盤上,從而解決磁盤性能的問題。
目前磁盤陣列結構有多種,包括 RAID 0、RAID 1、RAID 2、RAID 3、RAID 4、RAID 5、RAID 10/01、RAID 50等。其中RAID 2、RAID 3、RAID 4這三種陣列結構常用于陣列研究,生產環(huán)境中常使用的陣列結構為RAID 0、RAID 1、RAID 5和RAID 10/01。下面我們就對這些磁盤陣列結構逐一進行介紹。
5-1-1、RAID 0
RAID 0陣列結構是所有陣列結構中讀寫性能最好的,也是所有陣列結構中實現(xiàn)思路最簡單的:
RAID 0陣列結構沒有數(shù)據(jù)冗余機制和數(shù)據(jù)恢復機制,它至少需要兩個硬盤進行構造。整個RAID 0陣列結構就是將參與RAID 0陣列構建的所有硬盤進行容量累加,從而形成一個更大的、對上層操作系統(tǒng)統(tǒng)一的存儲容量。所以RAID 0陣列的存儲容量就是這些硬盤的容量進行累加。
當需要寫入的數(shù)據(jù)到達陣列控制器,后者會向其下的硬盤設備分發(fā)這些數(shù)據(jù)。這樣原來可能只由一個硬盤承擔的讀寫壓力就會被分擔到多個硬盤上,最終提高了整個陣列的讀寫性能。RAID 0陣列結構存儲速度的優(yōu)勢非常明顯,且參與構造陣列的磁盤數(shù)量越多陣列速度越快(峰值速度最終會受到總線、外部接口規(guī)范、控制芯片制造工藝等因素的限制)。但是RAID 0陣列結構的缺點也很明顯:由于陣列結構沒有容錯機制或者數(shù)據(jù)恢復機制,當陣列中的一個或者多個磁盤發(fā)生故障時,整個陣列結構就會崩潰并且不能恢復。所以在實際應用中,只有那些單位價值不高且每天又需要大量存儲的數(shù)據(jù)才會使用RAID 0陣列結構進行存儲,例如日志文件數(shù)據(jù)。
5-1-2、RAID 1
RAID 1陣列結構又被稱為磁盤鏡像陣列或者磁盤冗余陣列。它的構造特點是陣列結構中的每一個磁盤互為鏡像:
當有外部數(shù)據(jù)需要存儲時,RAID 1陣列控制器將會首先把這個數(shù)據(jù)做成N個副本(N的數(shù)量和陣列結構中物理磁盤的數(shù)量相等),實際上鏡像副本的單位為扇區(qū)或者Flash Page。這些副本會分別存儲到陣列結構的各個磁盤中。在進行數(shù)據(jù)讀取時,RAID 1 陣列結構中的某一塊磁盤將會作為主要的數(shù)據(jù)讀取源頭,當這個源頭出現(xiàn)吞吐量瓶頸時,RAID 1陣列控制器會主動到其它鏡像磁盤讀取數(shù)據(jù)。所以RAID 1陣列的數(shù)據(jù)讀取性能還是要比單個磁盤的性能要好,但是寫入性能卻差了很多。
從以上介紹可以看出,RAID 1陣列結構設計之初的主要目的并不是提高存儲設備的讀寫性能,而是保證高價值數(shù)據(jù)的存儲可靠性。由于RAID 1陣列結構中需要保證每個磁盤的鏡像數(shù)據(jù)完全一致,所以它還要求參與RAID 1陣列結構的每一個磁盤的容量必須相同,否則RAID 1陣列結構會以最小的那個磁盤容量為自己的標準容量。
5-1-3、RAID 10和RAID 01
RAID 0和RAID 1都有自己的優(yōu)缺點,并且這些特點都很突出:RAID 0雖然速度快但是沒有任何數(shù)據(jù)保障措施,所以一味地快意義并不大;RAID 1雖然保證了數(shù)據(jù)的可靠性,但是卻犧牲了大量空間和讀寫速度。所以以上兩種陣列結構特別是RAID 0,在企業(yè)級/工業(yè)級環(huán)境中使用的情況還是比較少。那么有沒有一種陣列結構在融合了RAID 0和RAID1兩者優(yōu)點的同時又避免了各自的缺點呢?
答案是:有的!RAID10和RAID01兩種陣列結構就是為了實現(xiàn)RAID 0和RAID 1的融合而被設計的。在RAID10結構中,它首先將參與陣列結構組建的磁盤進行分組,形成若干組獨立的RAID 1陣列結構,然后再將這些獨立的RAID 1陣列結構形成RAID 0結構,如下圖所示:
上圖中有四塊硬盤參與RAID 10陣列結構的組建,四塊硬盤是組建RAID 10陣列結構的最小要求(實際上兩塊也行,但是那樣的RAID 10沒有任何意義)。它們首先被兩兩分組形成兩個獨立的RAID 1結構,這也意味著這些硬盤的容量最好是一樣的,否則每組RAID 1結構會基于容量最小的那塊硬盤確認自己的容量。接著獨立工作的兩組RAID 1再組成RAID 0陣列結構。
假設參與RAID 10構建的硬盤大小都為6TB,則兩組獨立的RAID 1陣列結構的容量分別為12TB,最終整個RAID 10陣列結構的存儲容量為12TB。可以看到RAID10陣列結構的存儲容量和獨立磁盤的大小、分組數(shù)量有關。我們可以得到以下的計算公式:
RAID 10總容量 = N / G * 單個硬盤的存儲容量
這個公式假設的前提是參與RAID 10構建的每個硬盤的存儲容量都相同。其中N表示參與RAID 10構建的硬盤總數(shù),G代表RAID 10下磁盤映射的分組數(shù)量(RAID 1分組數(shù)量)。例如,總共12塊硬盤參與RAID 10構建,每個硬盤的大小為6TB,且分為三組RAID 1,那么這樣組建的RAID 10陣列結構的存儲容量為24TB;如果同樣的情況下,這些硬盤被分為四組RAID 1,那么組建的RAID 10陣列結構的存儲容量就為18TB。
可見RIAD 10通過集成更多硬盤的思路,將RAID 0陣列和RAID 1陣列的特點進行了融合,在保證數(shù)據(jù)存儲可靠性的基礎上提高了陣列的整體存儲性能。RAID 10被廣泛應用在各種計算場景中,市場上從幾千到幾百萬的陣列設備都提供對RAID 10磁盤陣列結構的支持。RAID 10磁盤陣列的總讀寫速度會受到控制芯片的影響,所以幾千和幾百萬的磁盤陣列設備實際讀寫性能是完全不一樣的 。
另外還有一種和RAID 10陣列結構相似的陣列結構:RAID 01(或稱為RAID 0 + 1),它們的構造區(qū)別是,后者首先將若干磁盤以RAID 0的方式進行組織,然后再分組成多個獨立的RAID 1結構:
5-1-5、RAID 5
RAID 5陣列結構和RAID 10/01陣列結構在實際生產環(huán)境中都經常被使用,前者的應用更為廣泛:雖然速度上RAID 5沒有RAID 10/01陣列結構快,但是RAID 5陣列控制芯片的成本卻低很多。RAID 5陣列基于奇偶校驗原理,它的算法核心是異或運算(XOR)。異或運算是各位讀者在大學離散數(shù)學課程中學習過的一種基本二進制運算,其運算關系如下表所述(以下表格的計算因子只有兩個,目的是讓讀者回憶起來):
接著我們可以再假設計算因子為N,根據(jù)異或運算的特點,我們可以在已知結果和N-1個原始計算因子的前提下,還原出未知的那個計算因子。請看下面示例的計算過程(N == 4):
......1 ^ 1 ^ 1 ^ ? = 1 -----> ? = 01 ^ 1 ^ 1 ^ ? = 0 -----> ? = 11 ^ 0 ^ 1 ^ ? = 1 -----> ? = 11 ^ 0 ^ 1 ^ ? = 0 -----> ? = 00 ^ 0 ^ 1 ^ ? = 1 -----> ? = 00 ^ 0 ^ 1 ^ ? = 0 -----> ? = 10 ^ 0 ^ 0 ^ ? = 1 -----> ? = 10 ^ 0 ^ 0 ^ ? = 0 -----> ? = 0......
有了以上的理論基礎,我們就可以將它應用到實際的塊存儲工作中。試想一下如果將以上異或運算的每個計算因子擴展成磁盤上的一個數(shù)據(jù)扇區(qū)并針對多個扇區(qū)進行異或運算并將計算結果存儲下來。那么是否可以在某一個數(shù)據(jù)扇區(qū)出現(xiàn)問題時恢復數(shù)據(jù)呢?答案是肯定的,請看如下扇區(qū)校驗實例:
在以上四個扇區(qū)的校驗示例中,它們分屬四個不同的磁盤設備,其中三個扇區(qū)存儲的是數(shù)據(jù),最后一個扇區(qū)存儲的是異或運算后的校驗碼。在上一篇文章中我們已經介紹過一個扇區(qū)存儲的數(shù)據(jù)量為512字節(jié)。當某個數(shù)據(jù)扇區(qū)出現(xiàn)故障時,基于校驗扇區(qū)的信息和正常狀態(tài)的數(shù)據(jù)扇區(qū)的信息,RAID 5磁盤陣列可以將發(fā)生故障的扇區(qū)恢復出來;當某個校驗扇區(qū)的信息出現(xiàn)故障時,RAID 5磁盤陣列還可以重新進行校驗。也就是說RAID 5陣列結構同一時間內只允許有一塊硬盤出現(xiàn)故障,出現(xiàn)故障的硬盤需要立即進行更換。
如果還未來得及更換故障硬盤,另一塊硬盤又出現(xiàn)了故障,那么對整個RAID 5陣列就是毀滅性的——因為無法通過異或計算同時恢復兩個計算因子。當更換故障硬盤后,RAID5陣列控制器將會自動對數(shù)據(jù)進行重新校驗,恢復數(shù)據(jù)。為了在可靠性和讀寫性能上找到平衡,RAID 5陣列結構會將存儲同一個文件的若干扇區(qū)分布在陣列下的若干磁盤上(設陣列中磁盤總數(shù)為N,則文件數(shù)據(jù)扇區(qū)分布于N-1個磁盤上),并將這些扇區(qū)的校驗信息存儲在最后剩余的一塊磁盤上;RAID 5陣列結構中,校驗信息也并不是全部存儲在一塊相同的磁盤上,而是均勻分布在每一塊磁盤中,這樣做的目的是為了盡可能快的完成數(shù)據(jù)恢復過程。
目前磁盤陣列設備被廣泛應用在從民用級計算到工業(yè)級計算的各個基礎領域,本小節(jié)的內容就帶各位讀者進行一些概要性了解。
最廉價的,也是在民用級市場上最普遍的做法,是將陣列控制器直接集成在主板上。RAID 0、RAID 1、RAID 5、RAID 10等陣列組織結構都可以在這種集成方式下提供支持。這些主板的價格可以做得很親民,但是這樣的陣列控制器集成方案也存在比較明顯的問題:支持的磁盤數(shù)量有限制,總的I/O吞吐性能也存在瓶頸。
另一種做法是將陣列控制器至于計算機以外,民用級市場和企業(yè)級市場上也經常使用這種集成方式,并且效果要好得多,因為至少從可集成的磁盤數(shù)量上來說就比上一種做法要好得多。但是由于制造成本的原因,這些外掛的磁盤陣列盒一般還是采用USB3.0等接口進行數(shù)據(jù)傳輸,所以吞吐性能上基本不會有太大提升:
企業(yè)級和工業(yè)級項目中,進行磁盤陣列方案實施時更多使用磁盤陣列柜和光纖接口。這樣可以緩解磁盤橫向擴展的問題和數(shù)據(jù)傳輸吞吐性能的問題。例如EMC提供的大型磁盤陣列設備:
通過以上1-5節(jié)的內容,我們向讀者介紹了位于塊存儲方案最底層的磁盤設備和陣列控制設備的工作原理和具體應用。特別是陣列控制設備,目前大量應用在商業(yè)級系統(tǒng)和工業(yè)及系統(tǒng)中,這樣的存儲方案也是應用最成熟的方案。那么操作系統(tǒng)為了抽象化這些底層設備的控制,就需要在操作系統(tǒng)層面組織一個管理文件數(shù)據(jù)邏輯地址的統(tǒng)一結構,以便向上層開發(fā)者屏蔽硬件操作細節(jié)。這樣的管理結構稱為文件系統(tǒng)。
目前主流的文件系統(tǒng)包括windows下的NTFS文件系統(tǒng)、Linux下的EXT系列文件系統(tǒng)(管理規(guī)則已升級到EXT4)、XFS文件系統(tǒng)和Btrfs文件系統(tǒng)。由于本專題的知識體系全部基于Linux操作系統(tǒng),所以我們不會對NTFS文件系統(tǒng)做過多介紹。在本文中我們主要介紹兩種Linux下的文件系統(tǒng):EXT系列文件系統(tǒng)和XFS文件系統(tǒng)。
6-1、EXT系列文件系統(tǒng)
EXT文件系統(tǒng)英文全稱:Extended file system。最初的EXT文件系統(tǒng)于1992年發(fā)布,用于替換之前使用的MINIX文件系統(tǒng)。經過多年的發(fā)展,目前EXT文件系統(tǒng)已經發(fā)展出4個版本,Ext1、Ext2、Ext3和Ext4。這些不同版本的文件系統(tǒng)中,雖然一些結構細節(jié)發(fā)生了變化(例如采用更快的Data blocks查找方式、采用更寬的索引位等),但這幾個版本中提現(xiàn)的文件系統(tǒng)設計思想?yún)s沒有太大的改變。
本節(jié)將從一個統(tǒng)一的文件系統(tǒng)數(shù)據(jù)組織結構開始講起,首先說明結構中重要區(qū)塊的作用,然后說明區(qū)塊間的關聯(lián)關系并推導一些關鍵的數(shù)據(jù)計算公式,最后再闡述幾個Ext文件系統(tǒng)版本的重要改進。
(Ext文件系統(tǒng)主要結構圖)
上圖描述了Ext文件系統(tǒng)主要結構。就如上文描述的那樣,不同的Ext文件系統(tǒng)版本對以上結構都有一定的調整,但是文件系統(tǒng)管理結構中的重要區(qū)塊的作用卻沒有發(fā)生什么變化,所以不會影響我們下文的講解。首先需要說明,操作系統(tǒng)層面建立文件系統(tǒng)的單位都是磁盤分區(qū),也就是說操作系統(tǒng)可以在一個物理磁盤上或者一個陣列管理設備上建立多種不同的文件系統(tǒng)。很多第三方分區(qū)工具都可以幫助開發(fā)人員/運維人員完成物理磁盤的分區(qū)操作。但是有一個問題需要特別說明一下:Linux系統(tǒng)下自帶的fdisk工具只能支持2TB的最大分區(qū)容量,如果需要分割出大于2TB容量的分區(qū),則需要使用Linux操作系統(tǒng)下的另一個工具parted,其根本原因是fdisk工具建立的是MBR分區(qū)表,而parted工具可以建立GPT分區(qū)表。
Ext系列文件系統(tǒng)的組織結構都是在進行格式化的時候就基于磁盤分區(qū)建立完畢的,以下示例腳本是針對一個名叫sdb1的磁盤分區(qū)成功建立Ext3文件系統(tǒng)后的顯示信息。
[root@localhost ~]# mkfs.ext3 /dev/sdb1mke2fs 1.41.12 (17-May-2010)Filesystem label=OS type: LinuxBlock size=4096 (log=2)Fragment size=4096 (log=2)Stride=0 blocks, Stripe width=0 blocks1310720 inodes, 5241198 blocks262059 blocks (5.00%) reserved for the super userFirst data block=0Maximum filesystem blocks=4294967296160 block groups32768 blocks per group, 32768 fragments per group8192 inodes per groupSuperblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000Writing inode tables: done Creating journal (32768 blocks): doneWriting superblocks and filesystem accounting information: done
以上腳本信息中有幾個關鍵點需要讀者注意,這幾個關鍵點將和后文敘述的信息形成對照:
Block size=4096和First data block=0:前一個信息說明Ext3文件系統(tǒng)中采用的每一個block的單位大小為4KB;后一個信息說明第一個Data block(Data block用于“真正”存儲文件數(shù)據(jù))的起始號。
Maximum filesystem blocks=4294967296:這個信息并不是說文件系統(tǒng)所在磁盤分區(qū)的最大block數(shù)量,而是說Ext3文件系統(tǒng)所支持的最大block數(shù)量。如果按照Block size=4096進行計算,那么4294967296 * 4096 = 16TB。這個值就是當block size為4KB時,Ext3文件系統(tǒng)理論上支持的最大容量(但實際上是無法達到這個容量的)。
160 block groups:這個信息表示Ext3文件系統(tǒng)被分為160個block group。下文中將進行block group的詳細介紹。這剛好和該Ext3文件系統(tǒng)的總容量是對應的:block groups * blocks per group * Block size = 160 * 32768 *4096 = 20,971,520 Byte = 20GB。
32768 blocks per group表示每一個block group組中所包含的block數(shù)量,這里的block并不單單指Data block,還包括block group中用來描述索引的inode table區(qū)域、可能預留的GDT區(qū)域、 block bitmap、inode bitmap等信息區(qū)域。
8192 inodes per group:這個信息表示了每一個block group中所包含的inode個數(shù)。inode個詳細結構將在后文中進行介紹
Superblock backups stored on blocks:Superblock區(qū)域存儲了Ext文件系統(tǒng)中非常重要的信息,這部分信息在一個Ext文件系統(tǒng)中有多個備份。這個信息向顯示文件系統(tǒng)完成格式化后,有哪些block存儲了Superblock區(qū)域的備份。
Creating journal (32768 blocks):journal日志區(qū)域和日志區(qū)域所占用的block數(shù)量,這個區(qū)域是Ext3、Ext4兩種文件系統(tǒng)所獨有的,Ext2文件系統(tǒng)中沒有這個區(qū)域。關于journal日志區(qū)域的作用后文也會進行詳細描述。
6-1-1、單個block group結構
上圖(Ext文件系統(tǒng)主要結構圖)中我們在sdb1磁盤分區(qū)上建立的Ext文件系統(tǒng),它的最頂層由若干個block group結構組成。他們在文件系統(tǒng)完成格式化的時候就被預先分配好了,所以如果您使用dumpe2fs命令查看某一個ext分區(qū)的分區(qū)狀態(tài)信息,就可以看到類似以下的信息(返回結果中段):
# 已省去大量狀態(tài)描述信息
[root@lab-backup ~]# dumpe2fs /dev/sdb1......dumpe2fs 1.41.12 (17-May-2010)......Filesystem flags: signed_directory_hash Default mount options: (none)Filesystem state: cleanErrors behavior: ContinueFilesystem OS type: LinuxInode count: 1310720Block count: 5241198Reserved block count: 262059Free blocks: 5114876Free inodes: 1310709First block: 0Block size: 4096Fragment size: 4096......Group 157: (Blocks 5144576-5177343) Block bitmap at 5144576 (+0), Inode bitmap at 5144577 (+1) Inode table at 5144578-5145089 (+2) 32254 free blocks, 8192 free inodes, 0 directories Free blocks: 5145090-5177343 Free inodes: 1286145-1294336Group 158: (Blocks 5177344-5210111) Block bitmap at 5177344 (+0), Inode bitmap at 5177345 (+1) Inode table at 5177346-5177857 (+2) 32254 free blocks, 8192 free inodes, 0 directories Free blocks: 5177858-5210111 Free inodes: 1294337-1302528Group 159: (Blocks 5210112-5241197) Block bitmap at 5210112 (+0), Inode bitmap at 5210113 (+1) Inode table at 5210114-5210625 (+2) 30572 free blocks, 8192 free inodes, 0 directories Free blocks: 5210626-5241197 Free inodes: 1302529-1310720......
dumpe2fs的主要作用就是返回指定分區(qū)上建立的文件系統(tǒng)中super block的檔案系統(tǒng)信息和每個block group組的信息。可以看到以上的命令顯示了“/dev/sdb1”的分區(qū)中一共有160個block group,并且至少從第157個block group開始,其中的inode記錄和block記錄都是空閑的。
在以上命令中指定的目標分區(qū)“/dev/sdb1”采用Ext3文件系統(tǒng)進行格式化,所以讀者看到的每一個分區(qū)的inode數(shù)量和block數(shù)據(jù)和我們后文的講解在數(shù)值上可能會有一些出入,但是不會影響去理解Ext系列文件系統(tǒng)管理文件數(shù)據(jù)的組織思路。那么每一個block group中包括的數(shù)據(jù)結構主要還有:
6-1-1-1: Super block
Super block從字面上可以理解成“超級塊”,其中存儲了文件系統(tǒng)非常關鍵的信息用于向使用者描述當前文件系統(tǒng)的狀態(tài),例如block與inode的使用情況(總量和已使用量)、每個inode的大小、文件系統(tǒng)掛載點等等信息(后文會給出重要信息項的介紹)。并不是所有block group中都有Super block,實際上一個Ext文件系統(tǒng)中,只有一個唯一的Super block信息區(qū)域,但為了保證Super block不會丟失,所以會有一部分block group對完整的Super block信息進行備份,這就是為什么我們在上一小節(jié)中,格式化成功后的返回信息中會有一個“Superblock backups stored on blocks”信息。以下是dumpe2fs命令針對“/dev/sdb1”分區(qū)上的文件系統(tǒng)所打印的另一段返回信息,這些信息都記錄在super block區(qū)域中:
[root@lab-backup ~]# dumpe2fs /dev/sdb1dumpe2fs 1.41.12 (17-May-2010)......Filesystem flags: signed_directory_hash Default mount options: (none)Filesystem state: cleanErrors behavior: ContinueFilesystem OS type: LinuxInode count: 1310720Block count: 5241198Reserved block count: 262059Free blocks: 5114876Free inodes: 1310709First block: 0Block size: 4096Fragment size: 4096Reserved GDT blocks: 1022Blocks per group: 32768Fragments per group: 32768Inodes per group: 8192Inode blocks per group: 512......Reserved blocks uid: 0 (user root)Reserved blocks gid: 0 (group root)First inode: 11Inode size: 256Required extra isize: 28Desired extra isize: 28Journal inode: 8Default directory hash: half_md4Directory Hash Seed: bd0a2065-d9ff-4abe-ad05-ded757287a0dJournal backup: inode blocksJournal features: (none)Journal size: 128MJournal length: 32768Journal sequence: 0x00000001Journal start: 0......
為了保證文件系統(tǒng)在磁盤部分扇區(qū)出現(xiàn)物理問題的情況下還能正常工作,就必須保證文件系統(tǒng)的super block信息在這種情況下也能正常訪問。所以一個文件系統(tǒng)的super block會在多個block group中進行備份,這些super block區(qū)域的數(shù)據(jù)保持一致。這里我們還需要對其中重要的參數(shù)項進行解釋,以便幫助后文描述block group的其他區(qū)域:
6-1-1-2:Group description table
這個區(qū)域的信息描述了當前這個block group中的其它數(shù)據(jù)區(qū)域的所在位置和使用情況,包括后面要介紹的block bitmap的起始位置、inode bitmap的起始位置、inode table的位置和使用情況以及blocks的使用情況。每一個block group的Group description table都在block group的狀態(tài)發(fā)生變化時一同變化。實際上各位讀者已經看過了Group description table的描述信息,就是上文6-1-1小節(jié)給出的命令返回示例中所顯示的另一段信息:
......Group 159: (Blocks 5210112-5241197) Block bitmap at 5210112 (+0), Inode bitmap at 5210113 (+1) Inode table at 5210114-5210625 (+2) 30572 free blocks, 8192 free inodes, 0 directories Free blocks: 5210626-5241197 Free inodes: 1302529-1310720......
6-1-1-3:Block bitmap 和 Inode bitmap
block group中的Block bitmap區(qū)域占用了4096字節(jié)(1個block),它用于幫助block group記錄哪些block已經使用哪些沒有使用。那么Block bitmap區(qū)域是如何完成這個工作任務的呢?Block bitmap區(qū)域的每一個bit都記錄本block group中的一個block的使用情況,0表示對應的block還沒有使用,如果為1則表示對應的block已被使用。既然Block bitmap區(qū)域占用了4096字節(jié),就表示block bitmap一共有4096 * 8 = 32768 bit,也就意味著一個block group中最多有32768的block。這剛好和Super block中描述的“Blocks per group”一致。我們來具體看一個Block bitmap中的記錄示例:
11110011? ?01010100? ?11101011 00000101 00000101 ?11100011? ......
以上Block bitmap區(qū)域中的數(shù)據(jù)表示:在這個block group中,block區(qū)域第0個block已經被使用了,第1個block已經被使用了。。。第4個block還沒有被使用。。。第12個block還沒有被使用。。。第30個block還沒有被使用。
Inode bitmap的作用是記錄block group中Inode區(qū)域的使用情況,Ext文件系統(tǒng)中一個block group中可以有16384個Inode,代表著這個Ext文件系統(tǒng)中一個block group最多可以描述16384個文件。在本文6-1-1小節(jié)中所給出的Ext3文件系統(tǒng)中,每個block group中有8192個Inode(“Inodes per group”參數(shù)描述)。每個Inode bitmap區(qū)域本身需要占據(jù)4096字節(jié),其描述block group中Inode區(qū)域使用情況時所使用的思路和Block bitmap區(qū)域使用的思路相似,不同的是Inode bitmap區(qū)域中所使用的4096字節(jié)中未對應Inode區(qū)域的部分將使用“1”進行填充。
6-1-1-4: Inode Table
在Ext2/Ext3文件系統(tǒng)中,每個文件在磁盤上的位置都由文件系統(tǒng)block group中的一個Inode指針進行索引,Inode將會把具體的位置指向一些真正記錄文件數(shù)據(jù)的block塊,需要注意的是這些block可能和Inode同屬于一個block group也可能分屬于不同的block group。我們把文件系統(tǒng)上這些真實記錄文件數(shù)據(jù)的block稱為Data blocks。我們將在下文中詳細介紹Inode的組織結構。
6-1-2、Inode Table和單個Inode 結構
Ext2/Ext3文件系統(tǒng)中,采用Inode指針和Data block地址進行直接/間接關聯(lián)的方式記錄文件數(shù)據(jù)。一個Inode指針要么不對應任何文件的Data block,要么對應一個文件的一個或者多個Data block。在Ext3文件系統(tǒng)中一個Inode指針的長度為4字節(jié),按照一個字節(jié)8個bit計算Ext3文件系統(tǒng)中的Inode指針支持32位Data block尋址(2 ^ 32個地址);到了Ext4文件系統(tǒng),雖然它不再使用Inode指針,但同樣有地址索引的概念,并且長度擴展到了6字節(jié),那么按照一個字節(jié)8個bit計算,Ext4文件系統(tǒng)中的索引支持48位Data block尋址(2 ^ 48個地址)。所以如果按照單個Data block記錄4KB數(shù)據(jù)大小來計算,Ext3文件系統(tǒng)支持的最大理論總容量就是:2 ^ 32 * 4KB / 1024 / 1024 / 1024 = 16TB,而Ext4文件系統(tǒng)支持的最大理論總容量就是 2 ^ 48 * 4KB / 1024 / 1024 / 1024 = 1,048,576TB = 1024 * 1024TB。
Ext2/Ext3文件系統(tǒng)的Inode信息存放在block group的Inode Table區(qū)域,這個區(qū)域的默認大小為512個block,那么再根據(jù)文件系統(tǒng)中單個Inode的大小就可以得到每個block group所管理的Inode總數(shù)。例如當單位Inode的大小為256字節(jié),得出每個block group所管理的Inode總數(shù)為 512 * 4096字節(jié) / 256字節(jié) = 8192(Ext4文件系統(tǒng));當Inode的大小為128字節(jié),得出每個block group所管理的Inode總數(shù)為 512 * 4096字節(jié) / 128字節(jié) = 16384 (Ext3文件系統(tǒng))
Ext2/Ext3文件系統(tǒng)中每個Inode結構中至少包括以下的信息:文件的權限定義、創(chuàng)建者、創(chuàng)建時間、最后一次修改事件、刪除時間、文件唯一編號以及12個直接關聯(lián)指針、1個間接關聯(lián)指針、1個兩級間接指針、1個三級間接指針、1個四級間接指針等。文件的權限定義等信息無需進行太多的說明,通過ls命令都可以查看到這些信息,這里重點講解一下Inode中的直接關聯(lián)指針和間接關聯(lián)指針。
所謂直接關聯(lián)是指Inode中4字節(jié)的信息直接指向一個Data block的位置,并可以從Data block中讀取文件數(shù)據(jù)。間接關聯(lián)是指Inode中4個字節(jié)的信息指向一個Data block,不過這個Data block中存儲的信息并不是真實的文件數(shù)據(jù)而是將這個Data block控制的4KB空間模擬成1024個新的Inode索引(Inode大小為4字節(jié),所以4KB / 4Byte = 1024),并分別指向若干新的Data blocks。
當從一個Inode開始,需要跳過一級這種模擬Inode的Data block才能到達真正用于記錄數(shù)據(jù)的Data block,這種關聯(lián)稱為間接關聯(lián),原始的Inode指針稱為間接關聯(lián)指針;當從一個Inode開始,需要跳過兩級這種模擬Inode的Data block才能到達真正用于記錄數(shù)據(jù)的Data block,這種關聯(lián)稱為兩級間接關聯(lián),原始的Inode指針稱為兩級間接關聯(lián)指針。。。以此類推Ext2、Ext3文件系統(tǒng)中最多支持四級間接關聯(lián)指針。這樣我們就可以計算出一個Inode支持的最大Data block數(shù)量,由于一個Inode最多對應一個文件,所以這個數(shù)量就可以推導出Ext2/Ext3系統(tǒng)中支持的單個文件的最大容量:
以上推導過程是在Ext3文件系統(tǒng)下,Inode尋址位寬為32位并且在進行文件系統(tǒng)格式化時設置的block大小為4KB的情況下進行的。如果在文件系統(tǒng)格式化時設置的block大小為8KB則系統(tǒng)支持的單個文件最大容量就變成了8TB。
6-2、Ext2和Ext3的區(qū)別
在上文6-1小節(jié)中介紹的Ext文件系統(tǒng)結構主要適用于Ext2和Ext3文件系統(tǒng),這兩個版本的Ext文件系統(tǒng)在數(shù)據(jù)組織結構上基本上沒有什么變化。Ext3文件系統(tǒng)相對于Ext2文件系統(tǒng)所做的主要優(yōu)化在數(shù)據(jù)寫入策略上。
6-2-1、Ext2寫入過程概要
Linux操作系統(tǒng)為了加快I/O操作過程,當有文件需要寫入文件系統(tǒng)時Linux操作系統(tǒng)并不會立刻將文件數(shù)據(jù)實際寫入data block,而是存儲到一個內存區(qū)塊中。如果您通過top命令或者Free命令,就可以看到這個名叫cache memory的內存區(qū)塊。
[root@lab-backup ~]# freetotal used free shared buffers cachedMem: 3805272 3662628 142644 508 1758376 1491128-/+ buffers/cache: 413124 3392148Swap: 3948540 0 3948540
無論是Ext2文件系統(tǒng)還是Ext3文件系統(tǒng)又或者是Ext4文件系統(tǒng),寫入cache memory區(qū)塊的這個過程是不會改變的。以上示例效果中還有一個叫做buffers memory的內存區(qū)塊,這個區(qū)塊緩存了文件系統(tǒng)的部分Inode信息,這樣保證了操作系統(tǒng)不會隨時到文件系統(tǒng)上尋找Inode——優(yōu)化文件系統(tǒng)的讀性能。cache memory區(qū)塊和buffers memory區(qū)塊由操作系統(tǒng)自行管理,它們只會使用當前沒有被應用程序占用的空閑內存。當應用程序請求新的內存區(qū)塊且空閑內存不夠時,操作系統(tǒng)會釋放部分cache memory區(qū)塊或者buffers memory區(qū)塊。后文我們講解Linux下的Page Cache技術時,還會對這部分只是進行詳細講解。當cache memory區(qū)塊寫滿或者到達一個等待時間后,操作系統(tǒng)就會正式開始向文件系統(tǒng)寫數(shù)據(jù)了。
在Ext2文件系統(tǒng)中,完成文件寫入的過程可以簡要的進行如下描述:首先文件系統(tǒng)會在收到文件寫入請求后根據(jù)算法尋找一個還沒有使用的Inode,這個算法過程根據(jù)不同文件系統(tǒng)小版本和Linux內核版本的不同而有所變化,但尋找原則都是一樣的,即盡可能為文件尋找連續(xù)的inode和data block。上文已經提到Ext文件系統(tǒng)中,每一個block group都有Block bitmap區(qū)域和Inode bitmap區(qū)域分別用于記錄block group中的block和Inode的使用情況。在尋找Inode的這個步驟中,block group的Block bitmap、Inode bitmap區(qū)域還不會被寫入任何變化,block group的Group description table區(qū)域也不會被寫入任何變化。
接下來Ext2文件系統(tǒng)就要向硬件層正式寫入數(shù)據(jù)了,這個步驟還包括建立Inode和data block的關聯(lián)信息。最后當文件系統(tǒng)相對空閑的情況下,文件系統(tǒng)才會更新block group中的Block bitmap、Inode bitmap和Group description table區(qū)域。正常情況下這種操作過程并沒有太大的問題,因為文件系統(tǒng)隨時都清楚哪些Block bitmap、Inode bitmap被真正使用了,哪些Block bitmap、Inode bitmap是被使用但還沒有來得及更改狀態(tài)。當文件系統(tǒng)正常關閉時Ext2文件系統(tǒng)會設置一個校驗標記Valid bit=1,表示本次文件系統(tǒng)的操作正常結束。
但是如果當文件系統(tǒng)因為各種原因異常關閉時(例如斷電)這個標記的值就為0,那么問題就來了。因為哪些已經被使用但還沒有來得及被標示的Block bitmap、Inode bitmap區(qū)域,和真實的使用情況就存在誤差了。雖然操作系統(tǒng)下次啟動時會對整個文件系統(tǒng)進行掃描試圖恢復操作(主要目的是恢復Block bitmap、Inode bitmap和真實事情情況的一致性),但是操作系統(tǒng)并不保證一致性被全部恢復。這樣看來Ext2文件系統(tǒng)的寫入過程至少存在一下幾個問題:
由于data block塊的寫入操作和Block bitmap、Inode bitmap區(qū)域的更新過程是分開進行的,所以當系統(tǒng)異常關閉時Ext2文件系統(tǒng)并不能保證Block bitmap、Inode bitmap的狀態(tài)和真實的block使用情況完全一致。所以才會有系統(tǒng)重啟時試圖恢復磁盤一致性的修復操作。
Ext2文件系統(tǒng)對于大文件的讀寫性能并不好,這是因為當文件特別大時,Ext2文件系統(tǒng)會啟用三級間接指針和四級間接指針建立Inode和data block的聯(lián)系。雖然當data block size為4KB時單個文件的大小可達4TB,但是因為存儲大文件時會啟用二級、三級甚至四級間接指針,這大大增加了文件系統(tǒng)上的索引查找時間。所以這種多級索引的思路除了可以增加單個文件容量外,對提升大文件的讀寫性能實際上并沒有太多幫助。
另外Ext2文件系統(tǒng)在向data block寫入文件數(shù)據(jù)時,將以data block size(默認為4KB)為單位依次向硬件層提交數(shù)據(jù),這就是為什么在其它設置不變的情況下,如果將Ext2文件系統(tǒng)的data block size格式化為8KB,會增加一定的磁盤讀寫性能的原因。
6-2-2、Ext3日志模式
以上小節(jié)中提到的Ext2文件系統(tǒng)的明顯問題中,最嚴重的應該還是文件系統(tǒng)異常情況下Block bitmap、Inode bitmap可能出現(xiàn)的一致性問題。所以Ext3文件系統(tǒng)在基本保持Ext2文件系統(tǒng)組織結構的前提下,使用索引日志的思路來解決Ext2文件系統(tǒng)上的數(shù)據(jù)一致性問題。
Ext3文件系統(tǒng)又被稱為日志文件系統(tǒng),它在Ext2文件系統(tǒng)的基礎上做的主要改動就是,在正式寫入data block數(shù)據(jù)并建立Inode索引前,通過在磁盤上的某塊固定位置寫入一段日志數(shù)據(jù)的方式建立這兩個操作過程的關系,并根據(jù)后續(xù)操作進行日志數(shù)據(jù)的保留/刪除,以達到保持操作一致性的目的。這樣一來,即使文件系統(tǒng)上一次異常關閉,當文件系統(tǒng)再次啟動時也不需要再進行整個文件系統(tǒng)Inode和data block掃描了,只需要重新加載日志數(shù)據(jù)文件系統(tǒng)就可以知道上一次異常關閉時還有哪些Block bitmap、Inode bitmap沒有處理完。
Ext3文件系統(tǒng)支持三種日志模式,他們在數(shù)據(jù)一致性和I/O性能上有所區(qū)別:
journal日志模式
在這種模式下,當文件系統(tǒng)正式開始進行磁盤操作前會在磁盤的上專門的日志區(qū)域創(chuàng)建這個文件的副本,包括這個文件的Inode和data block完整信息,副本創(chuàng)建完成后才會按照正常的寫入過程進行文件寫入。當寫入操作正常完成后,文件系統(tǒng)會刪除日志區(qū)域的文件副本。這樣一來當文件系統(tǒng)發(fā)生異常并重啟后,e2fsck檢測程序會掃描日志區(qū)域中的副本:如果發(fā)現(xiàn)文件副本本身就不完整,則會丟棄這部分副本。如果發(fā)現(xiàn)文件副本是完整的,則會繼續(xù)完成正式文件的寫入過程,最后刪除文件副本。很顯然journal日志模式會增加單個文件的磁盤操作次數(shù),所以journal日志模式是三種日志模式中速度最慢的一種。但是journal日志模式卻可以做到最完整的數(shù)據(jù)一致性要求。
ordered日志模式
ordered日志模式是Ext3/Ext4文件系統(tǒng)默認的日志模式。這種模式比 journal日志模式快了許多,因為ordered日志模式下Ext文件系統(tǒng)的日志區(qū)域并沒有真正記錄文件的真實數(shù)據(jù),不會發(fā)生一個文件的多次讀寫過程。當文件系統(tǒng)為新文件確定了Inode和block區(qū)域后,這些Inode、Block bitmap、Inode bitmap等索引信息將會首先保存到文件系統(tǒng)的日志區(qū)域,并形成一個事務單位。當文件數(shù)據(jù)被完整寫入磁盤對應的block后,文件系統(tǒng)才會將日志區(qū)域的Inode信息和block信息提交到對應的block group中,完成整個寫入過程。當文件系統(tǒng)發(fā)生異常并重啟后,e2fsck檢測程序會掃描日志區(qū)域中的副本:如果發(fā)現(xiàn)還有事務單位沒有被提交,那么磁盤上對應的block位置上的信息將被清除,以保持文件信息一致性。
writeback日志模式
這是一種異步日志模式,文件系統(tǒng)的日志區(qū)域雖然也記錄將寫入磁盤的新文件的Inode、Block bitmap、Inode bitmap等索引信息。但是和ordered日志模式不同的是,這些日志信息記錄過程和文件數(shù)據(jù)的寫入過程沒有先后關聯(lián),并且也不存在“提交”的概念。當文件系統(tǒng)發(fā)生異常并重啟后,e2fsck檢測程序也不會按照日志區(qū)域的數(shù)據(jù)狀態(tài)進行一致性修復。writeback日志模式在大多數(shù)情況下能夠提供最佳的Ext3/Ext4文件系統(tǒng)性能,因為日志功能幾乎是關閉的。
從以上三種Ext3文件系統(tǒng)日志模式的簡述中,可以發(fā)現(xiàn)的Ext3日志并不保證數(shù)據(jù)不丟失。實際上保證數(shù)據(jù)不丟失并不是Ext3日志的目標,而保證數(shù)據(jù)一致性才是Ext3日志的主要目標。為了達到這個目標,日志數(shù)據(jù)甚至會主動丟棄無法復原的副本數(shù)據(jù)。
6-2-3、設置文件系統(tǒng)日志級別
本小節(jié)介紹如何查看和設置Ext3/Ext4文件系統(tǒng)的日志模式。首先為了確定當前文件系統(tǒng)是否開啟了日志模式,可以使用dumpe2fs命令進行查看:
# dumpe2fs /dev/sdb2dumpe2fs 1.41.12 (17-May-2010)Filesystem volume name: <none>Last mounted on: <not available>Filesystem UUID: 0e94b563-8348-4056-8770-67fa34e2b903Filesystem magic number: 0xEF53Filesystem revision #: 1 (dynamic)Filesystem features: has_journal ext_attr resize_inode dir_index filetype......Journal backup: inode blocksJournal features: (none)日志大小: 128MJournal length: 32768Journal sequence: 0x00000001Journal start: 0......
以下的block group信息可以忽略
可以看到Filesystem features選項中有一個has_journal關鍵信息標識,這表示當前文件系統(tǒng)已經開啟了日志功能。如果沒有看到這個標記,則說明文件系統(tǒng)本身還沒有開啟日志功能——這種情況下Ext3文件系統(tǒng)就和Ext2文件系統(tǒng)沒有太大區(qū)別了。
以下命令可以開啟Ext3/Ext4文件系統(tǒng)的日志功能:
# tune2fs -O has_journal /dev/sdb2tune2fs 1.41.12 (17-May-2010)Creating journal inode: done
以下命令可以關閉Ext3/Ext4文件系統(tǒng)的日志功能:
# tune2fs -O ^has_journal /dev/sdb2tune2fs 1.41.12 (17-May-2010)
但必須注意這并不表示指定了具體的日志模式,在開啟了文件系統(tǒng)日志功能的情況下讀者可以在使用mount進行具體掛載時指定日志模式。如下所示:
mount -o data=journal /dev/sdb2 /mnt/hgfs/
以上命令的data參數(shù)部分可以換成ordered、writeback和journal,代表文件系統(tǒng)支持的三種日志模式。設置完成后文件一同也完成了掛載。但是怎么檢查日志模式設置是否成功呢?讀者可以通過dmesg命令查看Linux系統(tǒng)的內核日志,在日志的最后一行會有最近一次的掛載信息,類似如下:
# dmesg......EXT3-fs (sdb2): using internal journalEXT3-fs (sdb2): mounted filesystem with journal data modeSELinux: initialized (dev sdb2, type ext3), uses xattr
可以看到內核日志信息的最后一行信息說明最近完成的內核變動操作,是按照journal日志模式掛載sdb2分區(qū)。當然內核日志信息包含了很多無用的信息,讀者還可以通過以下命令索引出需要查看的信息:
# dmesg | grep -B 1 'mounted filesystem'......sd 2:0:0:0: [sda] Attached SCSI diskEXT4-fs (sda2): mounted filesystem with ordered data mode. Opts:--Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter OrubaEXT4-fs (sda1): mounted filesystem with ordered data mode. Opts:--EXT3-fs (sdb2): using internal journalEXT3-fs (sdb2): mounted filesystem with journal data mode......
當然最終我們還是要實現(xiàn)磁盤的永久掛載,這是就需要更改Linux操作系統(tǒng)中的/etc/fstab文件了。如果讀者使用的是文件系統(tǒng)默認的ordered日志模式,則不需要在/etc/fstab文件中進行額外的設置。但如果不是這樣的話,讀者在設置/etc/fstab文件時,就要在其中的options列說明文件系統(tǒng)使用的日志模式。類似如下所示:
# vim /etc/fstab....../dev/sdb2 /mnt/hgfs ext3 data=journal 0 0......
7、下文介紹
上一節(jié)我們討論了Ext3文件系統(tǒng)相對于Ext2文件系統(tǒng)最大的改進點——日志模式。但是Ext2文件系統(tǒng)中另外一個問題還沒有做太多調整:因為存儲大文件時Ext2/Ext3文件系統(tǒng)會啟用二級、三級甚至四級間接指針建立Inode和data block的聯(lián)系,這樣的做法會降低文件系統(tǒng)上對大文件的讀寫能力。
Ext4文件系統(tǒng)的細節(jié)文章就不再過多介紹了,因為系統(tǒng)存儲這個專題到到現(xiàn)在已經從最底層硬件設備開始到陣列結構再到操作系統(tǒng)上的文件系統(tǒng)進行了說明,相信讀者已經理解了為什么這種傳統(tǒng)的存儲方案被稱為塊存儲方案了。但是真正和軟件架構有關的知識卻還一點都沒有介紹。這顯然偏離了本專題最初規(guī)劃。
對Ext4文件系統(tǒng)有興趣的讀者可以繼續(xù)參考Ext官方文檔(
https://kernelnewbies.org/Ext4) ,從下文開始我們將轉入普遍搭建在塊存儲方案之上的關系型數(shù)據(jù)庫的相關知識介紹(主要為MySQL數(shù)據(jù)庫),包括影響關系型數(shù)據(jù)庫性能的重要因素、如何進行關系型數(shù)據(jù)庫集群的搭建。
————————————————
原文鏈接:
https://blog.csdn.net/yinwenjie/article/details/52430409
聯(lián)系客服