聊聊磁盤文件系統(一)
1 磁盤是怎樣工作的?
第一類,機械磁盤,也稱為硬盤驅動器(Hard Disk Driver),通常縮寫為 HDD。磁盤有多個盤片,每個盤片雙面存儲。磁道(Track)磁頭(Head)在盤片上畫出的不同半徑的同心圓。柱面(Cylinder)全部盤片相同磁道組成的圓柱側面。柱面是從0開始編號,由外向內。柱面越靠外,吞吐量越大。(因為越靠外轉動的線速度越大。扇區(Sector)盤片上的扇形區域。每個扇區512字節。是硬盤的基本單位。從1開始編號。每個扇區中的數據作為一個單元同時讀出或寫入。硬盤的0柱面0磁頭1扇區是系統啟動時首先讀取的扇區。
第二類,固態磁盤(Solid State Disk),通??s寫為 SSD,由固態電子元器件組成。固態磁盤不需要磁道尋址,所以,不管是連續 I/O,還是隨機 I/O 的性能,都比機械磁盤要好得多。
2 磁盤邏輯結構概觀
磁盤讀寫的最小單位是扇區,然而扇區只有 512B 大小,如果每次都讀寫這么小的單位,效率一定很低。所以,文件系統Ext又把連續的扇區組成了邏輯塊,然后每次都以邏輯塊為最小單元,來管理數據。常見的邏輯塊大小為 4KB,也就是由連續的 8 個扇區組成。a)如果是一個啟動盤,我們需要預留一塊區域作為引導區,所以第一個塊組的前面要留 1K,用于啟動引導區。b)磁盤在執行文件系統格式化時,會被分成三個存儲區域,超級塊、索引節點區和數據塊區。
- 索引節點:簡稱為 inode,用來記錄文件的元數據,比如 inode 編號、文件大小、訪問權限、修改日期、數據的位置等。索引節點和文件一一對應,它跟文件內容一樣,都會被持久化存儲到磁盤中。所以記住,索引節點同樣占用磁盤空間。
- 數據塊:簡稱為block,普通文件用來記錄文件的數據。目錄文件的塊里面保存的是目錄里面一項一項的文件信息,每一項都會保存這個目錄的下一級的文件的文件名和對應的 inode,通過這個 inode,就能找到真正的文件。第一項是“.”,表示當前目錄,第二項是“…”,表示上一級目錄,接下來就是一項一項的文件名和 inode。
- 超級塊:簡稱為super_block。用于存儲文件系統自身元數據的核心結構。其中的信息包括空閑和以使用塊的數目、塊長度、當前文件系統的狀態、各種時間戳。還包括一個表示文件系統類型的魔數,能檢查mount確認文件系統的類型是否正確。一般只使用塊組0中的超級塊,因此也叫主超級塊。如果主超級塊信息損壞,可以從超級塊的備份信息中復制數據來修復。c)另外還有幾個概念了解一下:
- 組描述符表(GDT):組描述符表包含的信息反映了文件系統中各個塊組的狀態。其中信息包含塊組中空閑塊和空閑inode的數目。每個塊組都包含了文件系統中所有塊組的組描述符信息。由于GDT對于定位文件系統的元數據非常重要,因此和超級塊一樣,也對其進行了備份。GDT及其備份的內容都是一樣的,所占塊數也相同。
- inode位圖:用二進制的方式記錄了inode的使用情況, 比如inode是否空閑等。
- 數據塊位圖:用二進制方式記錄了塊的使用情況。當查找或創建文件時,會掃描此位圖來尋找空閑的inode號對應的塊。一個塊組可以有32768(40968)個邏輯塊。每一個塊組均有自己的塊位圖與inode位圖,用于記錄本塊組中塊與inode的使用情況。一個邏輯塊的大小為4K。則一個塊位圖所描述的塊組最大為40968*4K=128MB。
- inode列表:包含了塊組中所有的inode,inode用于保存文件系統中與各個文件和目錄相連的所有元數據。
重要數據備份
默認情況下,超級塊和塊組描述符表都有副本保存在每一個塊組里面。如果開啟了 sparse_super(稀疏超級快) 特性,超級塊和塊組描述符表的副本只會保存在塊組索引為 0、3、5、7 的整數冪里。除了塊組 0 中存在一個超級塊外,在塊組 1(30=1)的第一個塊中存在一個副本;在塊組 3(31=3)、塊組 5(51=5)、塊組 7(71=7)、塊組 9(32=9)、塊組 25(52=25)、塊組 27(33=27)的第一個 block 處也存在一個副本。對于超級塊來講,由于超級塊不是很大,所以就算我們備份多了也沒有太多問題。但是,對于塊組描述符表來講,如果每個塊組里面都保存一份完整的塊組描述符表,一方面很浪費空間;另一個方面,由于一個塊組最大 128M,而塊組描述符表里面有多少項,這就限制了有多少個塊組,128M * 塊組的總數目是整個文件系統的大小,就被限制住了。這樣會產生一個限制,以Ext4的塊組描述符大小64 Bytes計算,文件系統中最多只能有2^21個塊組,也就是文件系統最大為256TB。
Flexible Block Groups
這是ext4引入的一個特點。就是將連續的多個block groups綁在一起組成一個邏輯塊組,稱之為flex_group。在一個flex_group中,第一個物理block group是存放當前flex_group全部的bitmap、inode表。也就是說將幾個塊組合并為一個更大的塊組。比如flex_group的大小為4(就是由4個塊組組成),其中的group0將按順序存放Super Block、GDT、4個塊組的塊位圖、4個塊組的inode位圖、4個塊組的inode表,剩余的空間是用作數據塊。就是說ext4將幾個塊組合并為一個更大的塊組。
flex_group塊組的作用是:
- 聚集元數據,加速元數據載入
- 使得大文件在磁盤上盡量連續 即使開啟flex_bg特性,超級塊和塊組描述符的冗余備份仍然位于塊組的開頭。Flex_bg中塊組的個數由2^ext4_super_block.s_log_groups_per_flex 給出。這是為了減少磁盤尋道操作,將頻繁訪問的塊組資源放在連續空間上。同時也能一次申請更多的塊;因為一次性申請的塊最大數目是一個組的塊數。
Ext4引入Meta Block Groups
首先,塊組描述符表不會保存所有塊組的描述符了,而是將塊組分成多個組,我們稱為元塊組(Meta Block Group)。每個元塊組里面的塊組描述符表僅僅包括自己的,一個元塊組包含 64 個塊組,這樣一個元塊組中的塊組描述符表最多 64 項。我們假設一共有 256 個塊組,原來是一個整的塊組描述符表,里面有 256 項,要備份就全備份,現在分成 4 個元塊組,每個元塊組里面的塊組描述符表就只有 64 項了,這就小多了,而且四個元塊組自己備份自己的。
根據圖中,每一個元塊組包含 64 個塊組,塊組描述符表也是 64 項,備份三份,在元塊組的第一個,第二個和最后一個塊組的開始處。這樣化整為零,我們就可以發揮出 ext4 的 48 位塊尋址的優勢了,在超級塊 ext4_super_block 的定義中,我們可以看到塊尋址分為高位和低位,均為 32 位,其中有用的是 48 位,2^48 個塊是 1EB,足夠用了。
- struct ext4_super_block {
- ......
- __le32 s_blocks_count_lo; /* Blocks count */
- __le32 s_r_blocks_count_lo; /* Reserved blocks count */
- __le32 s_free_blocks_count_lo; /* Free blocks count */
- ......
- __le32 s_blocks_count_hi; /* Blocks count */
- __le32 s_r_blocks_count_hi; /* Reserved blocks count */
- __le32 s_free_blocks_count_hi; /* Free blocks count */
- ......
- }
3 數據塊和Inode分配策略
在機械磁盤上,保持相關的數據塊相互接近可以總的磁頭移動時間,因而可以加速磁盤IO。在SSD上雖然沒有磁頭轉動,數據局部性可以增加每次IO請求的傳輸的數據大小,因而減少響應IO請求的傳輸次數。數據的局部性對單個擦除塊的寫入產生影響,可以加速文件重寫的速度。因而盡可能減少碎片是必要的。inode和數據塊的分配策略可以保證數據的局部集中。以下為inode和數據塊的分配策略:
- 多塊分配可以減少磁盤碎片。當文件初次創建的時候,塊分配器預測性地分配8KB的磁盤空間給文件。當文件關閉的時候,未使用的空間當然也就釋放了。但是如果推測是正確的,那么文件數據將寫到一個多個塊的extent中。
- 延遲分配。當一個文件需要更多的數據塊引起寫操作時,文件系統推遲決定新數據在磁盤上的存放位置,直到臟的buffer寫到磁盤為止。
- 盡量保持文件的數據塊與其inode在同一個塊組中??梢詼p少磁盤尋道時間.
- 盡量保持同一個目錄中的所有inodes與目錄位于同一個塊組中。這樣的假設前提是一個目錄中的文件是相關的。
- 磁盤卷被分成128MB的塊組。當在根目錄中創建目錄時,inode分配器掃描塊組并將新目錄放到它找到的使用負荷最小的塊組中。這可以保證目錄在磁盤上的分散性。
- 即使上述機制無效,仍然可以使用e4defrag整理碎片文件。
4 硬鏈接與軟鏈接
a)硬鏈接:
- 多個文件指向同一個inode,這些文件的inode number相同
- 硬鏈接表明文件可以通過不同的文件名訪問
- 不能對目錄創建硬鏈接
- 硬鏈接不能跨分區
- 每多一個硬鏈接,inode的引用計數(鏈接數)+1 b)軟鏈接(符號鏈接):
- 文件及其軟鏈接文件,使用的不是同一個inode,inode number不一樣;
- 軟鏈接文件的實際數據是另一個文件的路徑,是一個字符串,軟鏈接文件的大小為該字符串的長度;
- 可以對目錄創建軟鏈接
- 軟鏈接可以跨分區
- 增加文件軟鏈接,不會增加inode的引用計數