Linux上的新一代文件系統-Btrfs簡介

Linux上的新一代文件系統-Btrfs簡介

文件系統彷佛是內核中比較穩定的部分,多年來,人們一直使用 ext2/3,ext 文件系統以其卓越的穩定性成爲了事實上的 Linux 標準文件系統。php

近年來 ext2/3 暴露出了一些擴展性問題,因而便催生了 ext4。在2008年發佈的 Linux2.6.19 內核中集成了 ext4 的 dev 版本。2.6.28內核發佈時,ext4 結束了開發版,開始接受用戶的使用。彷佛 ext 就將成爲 Linux 文件系統的代名詞。然而當您閱讀不少有關 ext4 的文章時,會發現都不約而同地提到了 btrfs,並認爲 ext4 將是一個過渡的文件系統。 ext4 的做者 Theodore Tso 也盛讚 btrfs 並認爲 btrfs 將成爲下一代 Linux 標準文件系統。 Oracle,IBM, Intel 等廠商也對 btrfs 表現出了極大的關注,投入了資金和人力。爲何 btrfs 如此受人矚目呢。這即是本文首先想探討的問題。html

Kevin Bowling[1] 有一篇介紹各類文件系統的文章,在他看來,ext2/3 等文件系統屬於「古典時期」。文件系統的新時代是 2005 年由 Sun 公司的 ZFS 開創的。 ZFS 表明」 last word in file system 」,意思是此後不再須要開發其餘的文件系統了。 ZFS 的確帶來了不少嶄新的觀念,對文件系統來說是一個劃時代的做品。node

若是您比較 btrfs 的特性,將會發現 btrfs 和 ZFS 很是相似。也許咱們能夠認爲 btrfs 就是 Linux 社區對 ZFS 所做出的迴應。今後日後在 Linux 中也終於有了一個能夠和 ZFS 相媲美的文件系統。linux

btrfs 的特性

您能夠在 btrfs 的主頁上 [2] 看到 btrfs 的特性列表。我自做主張,將那張列表分紅了四大部分。算法

首先是擴展性 (scalability) 相關的特性,btrfs 最重要的設計目標是應對大型機器對文件系統的擴展性要求。 Extent,B-Tree 和動態 inode 建立等特性保證了 btrfs 在大型機器上仍有卓越的表現,其總體性能而不會隨着系統容量的增長而下降。數據庫

其次是數據一致性 (data integrity) 相關的特性。系統面臨不可預料的硬件故障,Btrfs 採用 COW 事務技術來保證文件系統的一致性。 btrfs 還支持 checksum,避免了 silent corrupt 的出現。而傳統文件系統則沒法作到這一點。安全

第三是和多設備管理相關的特性。 Btrfs 支持建立快照 (snapshot),和克隆 (clone) 。 btrfs 還可以方便的管理多個物理設備,使得傳統的卷管理軟件變得多餘。網絡

最後是其餘難以歸類的特性。這些特性都是比較先進的技術,可以顯著提升文件系統的時間 / 空間性能,包括延遲分配,小文件的存儲優化,目錄索引等。數據結構

擴展性相關的特性

B-Tree異步

btrfs 文件系統中全部的 metadata 都由 BTree 管理。使用 BTree 的主要好處在於查找,插入和刪除操做都很高效。能夠說 BTree 是 btrfs 的核心。

一味地誇耀 BTree 很好很高效也許並不能讓人信服,但假如稍微花費一點兒時間看看 ext2/3 中元數據管理的實現方式,即可以反襯出 BTree 的優勢。

妨礙 ext2/3 擴展性的一個問題來自其目錄的組織方式。目錄是一種特殊的文件,在 ext2/3 中其內容是一張線性表格。如圖 1-1 所示 [6]:

圖 1. ext2 directory [6]

ext2 directory

圖 1 展現了一個 ext2 目錄文件的內容,該目錄中包含四個文件。分別是 "home1","usr","oldfile" 和 "sbin" 。若是須要在該目錄中查找目錄 sbin,ext2 將遍歷前三項,直至找到 sbin 這個字符串爲止。

這種結構在文件個數有限的狀況下是比較直觀的設計,但隨着目錄下文件數的增長,查找文件的時間將線性增加。 2003 年,ext3 設計者開發了目錄索引技術,解決了這個問題。目錄索引使用的數據結構就是 BTree 。若是同一目錄下的文件數超過 2K,inode 中的 i_data 域指向一個特殊的 block 。在該 block 中存儲着目錄索引 BTree 。 BTree 的查找效率高於線性表,

但爲同一個元數據設計兩種數據結構老是不太優雅。在文件系統中還有不少其餘的元數據,用統一的 BTree 管理是很是簡單而優美的設計。

Btrfs 內部全部的元數據都採用 BTree 管理,擁有良好的可擴展性。 btrfs 內部不一樣的元數據由不一樣的 Tree 管理。在 superblock 中,有指針指向這些 BTree 的根。如圖 2 所示:

圖 2. btrfs btree

btrfs btree

FS Tree 管理文件相關的元數據,如 inode,dir 等; Chunk tree 管理設備,每個磁盤設備都在 Chunk Tree 中有一個 item ; Extent Tree 管理磁盤空間分配,btrfs 每分配一段磁盤空間,便將該磁盤空間的信息插入到 Extent tree 。查詢 Extent Tree 將獲得空閒的磁盤空間信息; Tree of tree root 保存不少 BTree 的根節點。好比用戶每創建一個快照,btrfs 便會建立一個 FS Tree 。爲了管理全部的樹,btrfs 採用 Tree of tree root 來保存全部樹的根節點; checksum Tree 保存數據塊的校驗和。

基於 Extent 的文件存儲

現代不少文件系統都採用了 extent 替代 block 來管理磁盤。 Extent 就是一些連續的 block,一個 extent 由起始的 block 加上長度進行定義。

Extent 能有效地減小元數據開銷。爲了進一步理解這個問題,咱們仍是看看 ext2 中的反面例子。

ext2/3 以 block 爲基本單位,將磁盤劃分爲多個 block 。爲了管理磁盤空間,文件系統須要知道哪些 block 是空閒的。 Ext 使用 bitmap 來達到這個目的。 Bitmap 中的每個 bit 對應磁盤上的一個 block,當相應 block 被分配後,bitmap 中的相應 bit 被設置爲 1 。這是很經典也很清晰的一個設計,但不幸的是當磁盤容量變大時,bitmap 自身所佔用的空間也將變大。這就致使了擴展性問題,隨着存儲設備容量的增長,bitmap 這個元數據所佔用的空間也隨之增長。而人們但願不管磁盤容量如何增長,元數據不該該隨之線形增長,這樣的設計才具備可擴展性。

下圖比較了 block 和 extent 的區別:

圖 3. 採用 extent 的 btrfs 和採用 bitmap 的 ext2/3

採用extent的btrfs和採用bitmap的ext2/3

在 ext2/3 中,10 個 block 須要 10 個 bit 來表示;在 btrfs 中則只須要一個元數據。對於大文件,extent 表現出了更加優異的管理性能。

Extent 是 btrfs 管理磁盤空間的最小單位,由 extent tree 管理。 Btrfs 分配 data 或 metadata 都須要查詢 extent tree 以便得到空閒空間的信息。

動態 inode 分配

爲了理解動態 inode 分配,仍是須要藉助 ext2/3 。下表列舉了 ext2 文件系統的限制:

表 1. ext2 限制

  限制
最大文件數量 文件系統空間大小 V / 8192
好比 100G 大小的文件系統中,能建立的文件個數最大爲 131072

圖 4 顯示了 ext2 的磁盤佈局:

圖 4. ext2 layout

ext2 layout

在 ext2 中 inode 區是被預先固定分配的,且大小固定,好比一個 100G 的分區中,inode table 區中只能存放 131072 個 inode,這就意味着不可能建立超過 131072 個文件,由於每個文件都必須有一個惟一的 inode 。

爲了解決這個問題,必須動態分配 inode 。每個 inode 只是 BTree 中的一個節點,用戶能夠無限制地任意插入新的 inode,其物理存儲位置是動態分配的。因此 btrfs 沒有對文件個數的限制。

針對 SSD 的優化支持

SSD 是固態存儲 Solid State Disk 的簡稱。在過去的幾十年中,CPU/RAM 等器件的發展始終遵循着摩爾定律,但硬盤 HDD 的讀寫速率卻始終沒有飛躍式的發展。磁盤 IO 始終是系統性能的瓶頸。

SSD 採用 flash memory 技術,內部沒有磁盤磁頭等機械裝置,讀寫速率大幅度提高。 flash memory 有一些不一樣於 HDD 的特性。 flash 在寫數據以前必須先執行擦除操做;其次,flash 對擦除操做的次數有必定的限制,在目前的技術水平下,對同一個數據單元最多能進行約 100 萬次擦除操做,所以,爲了延長 flash 的壽命,應該將寫操做平均到整個 flash 上。

SSD 在硬件內部的微代碼中實現了 wear leveling 等分佈寫操做的技術,所以系統無須再使用特殊的 MTD 驅動和 FTL 層。雖然 SSD 在硬件層面作了不少努力,但畢竟仍是有限。文件系統針對 SSD 的特性作優化不只能提升 SSD 的使用壽命,並且能提升讀寫性能。 Btrfs 是少數專門對 SSD 進行優化的文件系統。 btrfs 用戶可使用 mount 參數打開對 SSD 的特殊優化處理。

Btrfs 的 COW 技術從根本上避免了對同一個物理單元的反覆寫操做。若是用戶打開了 SSD 優化選項,btrfs 將在底層的塊空間分配策略上進行優化:將屢次磁盤空間分配請求聚合成一個大小爲 2M 的連續的塊。大塊連續地址的 IO 可以讓固化在 SSD 內部的微代碼更好的進行讀寫優化,從而提升 IO 性能。

數據一致性相關的特性

COW 事務

理解 COW 事務,必須首先理解 COW 和事務這兩個術語。

什麼是 COW?

所謂 COW,即每次寫磁盤數據時,先將更新數據寫入一個新的 block,當新數據寫入成功以後,再更新相關的數據結構指向新 block 。

什麼是事務?

COW 只能保證單一數據更新的原子性。但文件系統中不少操做須要更新多個不一樣的元數據,好比建立文件須要修改如下這些元數據:

  1. 修改 extent tree,分配一段磁盤空間
  2. 建立一個新的 inode,並插入 FS Tree 中
  3. 增長一個目錄項,插入到 FS Tree 中

任何一個步驟出錯,文件便不能建立成功,所以能夠定義爲一個事務。

下面將演示一個 COW 事務。

A 是 FS Tree 的根節點,新的 inode 的信息將被插入節點 C 。首先,btrfs 將 inode 插入一個新分配的 block C ’中,並修改上層節點 B,使其指向新的 block C ’;修改 B 也將引起 COW,以此類推,引起一個連鎖反應,直到最頂層的 Root A 。當整個過程結束後,新節點 A ’變成了 FS Tree 的根。但此時事務並未結束,superblock 依然指向 A 。

圖 5. COW transaction 1

COW transaction 1

接下來,修改目錄項(E 節點),一樣引起這一過程,從而生成新的根節點 A ’’。

圖 6. COW transaction 2

COW transaction 2

此時,inode 和目錄項都已經寫入磁盤,能夠認爲事務已經結束。 btrfs 修改 superblock,使其指向 A ’’,以下圖所示:

圖 7. COW transaction 3

COW transaction 3

COW 事務可以保證文件系統的一致性,而且系統 Reboot 以後不須要執行 fsck 。由於 superblock 要麼指向新的 A ’’,要麼指向 A,不管哪一個都是一致的數據。

Checksum

Checksum 技術保證了數據的可靠性,避免 silent corruption 現象。因爲硬件緣由,從磁盤上讀出的數據會出錯。好比 block A 中存放的數據爲 0x55,但讀取出來的數據變是 0x54,由於讀取操做並未報錯,因此這種錯誤不能被上層軟件所察覺。

解決這個問題的方法是保存數據的校驗和,在讀取數據後檢查校驗和。若是不符合,便知道數據出現了錯誤。

ext2/3 沒有校驗和,對磁盤徹底信任。而不幸的是,磁盤的錯誤始終存在,不只發生在廉價的 IDE 硬盤上,昂貴的 RAID 也存在 silent corruption 問題。並且隨着存儲網絡的發展,即便數據從磁盤讀出正確,也很難確保可以安全地穿越網絡設備。

btrfs 在讀取數據的同時會讀取其相應的 checksum 。若是最終從磁盤讀取出來的數據和 checksum 不相同,btrfs 會首先嚐試讀取數據的鏡像備份,若是數據沒有鏡像備份,btrfs 將返回錯誤。寫入磁盤數據以前,btrfs 計算數據的 checksum 。而後將 checksum 和數據同時寫入磁盤。

Btrfs 採用單獨的 checksum Tree 來管理數據塊的校驗和,把 checksum 和 checksum 所保護的數據塊分離開,從而提供了更嚴格的保護。假如在每一個數據 block 的 header 中加入一個域保存 checksum,那麼這個數據 block 就成爲一個本身保護本身的結構。這種結構下有一種錯誤沒法檢測出來,好比原本文件系統打算從磁盤上讀 block A,但返回了 block B,因爲 checksum 在 block 內部,所以 checksum 依舊是正確的。 btrfs 採用 checksum tree 來保存數據塊的 checksum,避免了上述問題。

Btrfs 採用 crc32 算法計算 checksum,在未來的開發中會支持其餘類型的校驗算法。爲了提升效率,btrfs 將寫數據和 checksum 的工做分別用不一樣的內核線程並行執行。

多設備管理相關的特性

每一個 Unix 管理員都曾面臨爲用戶和各類應用分配磁盤空間的任務。多數狀況下,人們沒法事先準確地估計一個用戶或者應用在將來究竟須要多少磁盤空間。磁盤空間被用盡的狀況常常發生,此時人們不得不試圖增長文件系統空間。傳統的 ext2/3 沒法應付這種需求。

不少卷管理軟件被設計出來知足用戶對多設備管理的需求,好比 LVM 。 Btrfs 集成了卷管理軟件的功能,一方面簡化了用戶命令;另外一方面提升了效率。

多設備管理

Btrfs 支持動態添加設備。用戶在系統中增長新的磁盤以後,可使用 btrfs 的命令將該設備添加到文件系統中。

爲了靈活利用設備空間,Btrfs 將磁盤空間劃分爲多個 chunk 。每一個 chunk 可使用不一樣的磁盤空間分配策略。好比某些 chunk 只存放 metadata,某些 chunk 只存放數據。一些 chunk 能夠配置爲 mirror,而另外一些 chunk 則能夠配置爲 stripe 。這爲用戶提供了很是靈活的配置可能性。

Subvolume

Subvolume 是很優雅的一個概念。即把文件系統的一部分配置爲一個完整的子文件系統,稱之爲 subvolume 。

採用 subvolume,一個大的文件系統能夠被劃分爲多個子文件系統,這些子文件系統共享底層的設備空間,在須要磁盤空間時便從底層設備中分配,相似應用程序調用 malloc() 分配內存同樣。能夠稱之爲存儲池。這種模型有不少優勢,好比能夠充分利用 disk 的帶寬,能夠簡化磁盤空間的管理等。

所謂充分利用 disk 的帶寬,指文件系統能夠並行讀寫底層的多個 disk,這是由於每一個文件系統均可以訪問全部的 disk 。傳統的文件系統不能共享底層的 disk 設備,不管是物理的仍是邏輯的,所以沒法作到並行讀寫。

所謂簡化管理,是相對於 LVM 等卷管理軟件而言。採用存儲池模型,每一個文件系統的大小均可以自動調節。而使用 LVM,若是一個文件系統的空間不夠了,該文件系統並不能自動使用其餘磁盤設備上的空閒空間,而必須使用 LVM 的管理命令手動調節。

Subvolume 能夠做爲根目錄掛載到任意 mount 點。 subvolume 是很是有趣的一個特性,有不少應用。

假如管理員只但願某些用戶訪問文件系統的一部分,好比但願用戶只能訪問 /var/test/ 下面的全部內容,而不能訪問 /var/ 下面其餘的內容。那麼即可以將 /var/test 作成一個 subvolume 。 /var/test 這個 subvolume 即是一個完整的文件系統,能夠用 mount 命令掛載。好比掛載到 /test 目錄下,給用戶訪問 /test 的權限,那麼用戶便只能訪問 /var/test 下面的內容了。

快照和克隆

快照是對文件系統某一時刻的徹底備份。創建快照以後,對文件系統的修改不會影響快照中的內容。這是很是有用的一種技術。

好比數據庫備份。假如在時間點 T1,管理員決定對數據庫進行備份,那麼他必須先中止數據庫。備份文件是很是耗時的操做,假如在備份過程當中某個應用程序修改了數據庫的內容,那麼將沒法獲得一個一致性的備份。所以在備份過程當中數據庫服務必須中止,對於某些關鍵應用這是不能容許的。

利用快照,管理員能夠在時間點 T1 將數據庫中止,對系統創建一個快照。這個過程通常只須要幾秒鐘,而後就能夠當即從新恢復數據庫服務。此後在任什麼時候候,管理員均可以對快照的內容進行備份操做,而此時用戶對數據庫的修改不會影響快照中的內容。當備份完成,管理員即可以刪除快照,釋放磁盤空間。

快照通常是隻讀的,當系統支持可寫快照,那麼這種可寫快照便被稱爲克隆。克隆技術也有不少應用。好比在一個系統中安裝好基本的軟件,而後爲不一樣的用戶作不一樣的克隆,每一個用戶使用本身的克隆而不會影響其餘用戶的磁盤空間。很是相似於虛擬機。

Btrfs 支持 snapshot 和 clone 。這個特性極大地增長了 btrfs 的使用範圍,用戶不須要購買和安裝昂貴而且使用複雜的卷管理軟件。下面簡要介紹一下 btrfs 實現快照的基本原理。

如前所述 Btrfs 採用 COW 事務技術,從圖 1-10 能夠看到,COW 事務結束後,若是不刪除原來的節點 A,C,E,那麼 A,C,E,D,F 依然完整的表示着事務開始以前的文件系統。這就是 snapshot 實現的基本原理。

Btrfs 採用引用計數決定是否在事務 commit 以後刪除原有節點。對每個節點,btrfs 維護一個引用計數。當該節點被別的節點引用時,該計數加一,當該節點再也不被別的節點引用時,該計數減一。當引用計數歸零時,該節點被刪除。對於普通的 Tree Root, 引用計數在建立時被加一,由於 Superblock 會引用這個 Root block 。很明顯,初始狀況下這棵樹中的全部其餘節點的引用計數都爲一。當 COW 事務 commit 時,superblock 被修改指向新的 Root A ’’,原來 Root block A 的引用計數被減一,變爲零,所以 A 節點被刪除。 A 節點的刪除會引起其子孫節點的引用計數也減一,圖 1-10 中的 B,C 節點的引用計數所以也變成了 0,從而被刪除。 D,E 節點在 COW 時,由於被 A ’’所引用,計數器加一,所以計數器這時並未歸零,從而沒有被刪除。

建立 Snapshot 時,btrfs 將的 Root A 節點複製到 sA,並將 sA 的引用計數設置爲 2 。在事務 commit 的時候,sA 節點的引用計數不會歸零,從而不會被刪除,所以用戶能夠繼續經過 Root sA 訪問 snapshot 中的文件。

圖 8. Snapshot

Snapshot

軟件 RAID

RAID 技術有不少很是吸引人的特性,好比用戶能夠將多個廉價的 IDE 磁盤組合爲 RAID0 陣列,從而變成了一個大容量的磁盤; RAID1 和更高級的 RAID 配置還提供了數據冗餘保護,從而使得存儲在磁盤中的數據更加安全。

Btrfs 很好的支持了軟件 RAID,RAID 種類包括 RAID0,RAID1 和 RAID10.

Btrfs 缺省狀況下對 metadata 進行 RAID1 保護。前面已經說起 btrfs 將設備空間劃分爲 chunk,一些 chunk 被配置爲 metadata,即只存儲 metadata 。對於這類 chunk,btrfs 將 chunk 分紅兩個條帶,寫 metadata 的時候,會同時寫入兩個條帶內,從而實現對 metadata 的保護。

其餘特性

Btrfs 主頁上羅列的其餘特性不容易分類,這些特性都是現代文件系統中比較先進的技術,可以提升文件系統的時間或空間效率。

Delay allocation

延遲分配技術可以減小磁盤碎片。在 Linux 內核中,爲了提升效率,不少操做都會延遲。

在文件系統中,小塊空間頻繁的分配和釋放會形成碎片。延遲分配是這樣一種技術,當用戶須要磁盤空間時,先將數據保存在內存中。並將磁盤分配需求發送給磁盤空間分配器,磁盤空間分配器並不當即分配真正的磁盤空間。只是記錄下這個請求便返回。

磁盤空間分配請求可能很頻繁,因此在延遲分配的一段時間內,磁盤分配器能夠收到不少的分配請求,一些請求也許能夠合併,一些請求在這段延遲期間甚至可能被取消。經過這樣的「等待」,每每可以減小沒必要要的分配,也有可能將多個小的分配請求合併爲一個大的請求,從而提升 IO 效率。

Inline file

系統中每每存在大量的小文件,好比幾百個字節或者更小。若是爲其分配單獨的數據 block,便會引發內部碎片,浪費磁盤空間。 btrfs 將小文件的內容保存在元數據中,再也不額外分配存放文件數據的磁盤塊。改善了內部碎片問題,也增長了文件的訪問效率。

圖 9. inline file

inline file

上圖顯示了一個 BTree 的葉子節點。葉子中有兩個 extent data item 元數據,分別用來表示文件 file1 和 file2 所使用的磁盤空間。

假設 file1 的大小僅爲 15 個字節; file2 的大小爲 1M 。如圖所示,file2 採用普通的 extent 表示方法:extent2 元數據指向一段 extent,大小爲 1M,其內容即是 file2 文件的內容。

而對於 file1, btrfs 會把其文件內容內嵌到元數據 extent1 中。若是不採用 inline file 技術。如虛線所示,extent1 指向一個最小的 extent,即一個 block,但 file1 有 15 個字節,其他的空間便成爲了碎片空間。

採用 inline 技術,讀取 file1 時只須要讀取元數據 block,而無需先讀取 extent1 這個元數據,再讀取真正存放文件內容的 block,從而減小了磁盤 IO 。

得益於 inline file 技術,btrfs 處理小文件的效率很是高,也避免了磁盤碎片問題。

目錄索引 Directory index

當一個目錄下的文件數目巨大時,目錄索引能夠顯著提升文件搜索時間。 Btrfs 自己採用 BTree 存儲目錄項,因此在給定目錄下搜索文件的效率是很是高的。

然而,btrfs 使用 BTree 管理目錄項的方式沒法同時知足 readdir 的需求。 readdir 是 POSIX 標準 API,它要求返回指定目錄下的全部文件,而且特別的,這些文件要按照 inode number 排序。而 btrfs 目錄項插入 BTree 時的 Key 並非 Inode number,而是根據文件名計算的一個 hash 值。這種方式在查找一個特定文件時很是高效,但卻不適於 readdir 。爲此,btrfs 在每次建立新的文件時,除了插入以 hash 值爲 Key 的目錄項外,還同時插入另一種目錄項索引,該目錄項索引的 KEY 以 sequence number 做爲 BTree 的鍵值。這個 sequence number 在每次建立新文件時線性增長。由於 Inode number 也是每次建立新文件時增長的,因此 sequence number 和 inode number 的順序相同。以這種 sequence number 做爲 KEY 在 BTree 中查找即可以方便的獲得一個以 inode number 排序的文件列表。

另外以 sequence number 排序的文件每每在磁盤上的位置也是相鄰的,因此以 sequence number 爲序訪問大量文件會得到更好的 IO 效率。

壓縮

你們都曾使用過 zip,winrar 等壓縮軟件,將一個大文件進行壓縮能夠有效節約磁盤空間。 Btrfs 內置了壓縮功能。

一般人們認爲將數據寫入磁盤以前進行壓縮會佔用不少的 CPU 計算時間,必然下降文件系統的讀寫效率。但隨着硬件技術的發展,CPU 處理時間和磁盤 IO 時間的差距不斷加大。在某些狀況下,花費必定的 CPU 時間和一些內存,但卻能大大節約磁盤 IO 的數量,這反而可以增長總體的效率。

好比一個文件不通過壓縮的狀況下須要 100 次磁盤 IO 。但花費少許 CPU 時間進行壓縮後,只須要 10 次磁盤 IO 就能夠將壓縮後的文件寫入磁盤。在這種狀況下,IO 效率反而提升了。固然,這取決於壓縮率。目前 btrfs 採用 zlib 提供的 DEFALTE/INFLATE 算法進行壓縮和解壓。在未來,btrfs 應該能夠支持更多的壓縮算法,知足不一樣用戶的不一樣需求。

目前 btrfs 的壓縮特性還存在一些不足,當壓縮使能後,整個文件系統下的全部文件都將被壓縮,但用戶可能須要更細粒度的控制,好比針對不一樣的目錄採用不一樣的壓縮算法,或者禁止壓縮。我相信,btrfs 開發團隊將在從此的版本中解決這個問題。

對於某些類型的文件,好比 jpeg 文件,已經沒法再進行壓縮。嘗試對其壓縮將純粹浪費 CPU 。爲此,當對某文件的若干個 block 壓縮後發現壓縮率不佳,btrfs 將不會再對文件的其他部分進行壓縮操做。這個特性在某種程度上提升了文件系統的 IO 效率。

預分配

不少應用程序有預先分配磁盤空間的須要。他們能夠經過 posix_fallocate 接口告訴文件系統在磁盤上預留一部分空間,但暫時並不寫入數據。若是底層文件系統不支持 fallocate,那麼應用程序只有使用 write 預先寫一些無用信息以便爲本身預留足夠的磁盤空間。

由文件系統來支持預留空間更加有效,並且可以減小磁盤碎片,由於全部的空間都是一次分配,於是更有可能使用連續的空間。 Btrfs 支持 posix_fallocate 。

總結

至此,咱們對 btrfs 的不少特性進行了較爲詳細的探討,但 btrfs 能提供的特性卻並不止這些。 btrfs 正處於試驗開發階段,還將有更多的特性。

Btrfs 也有一個重要的缺點,當 BTree 中某個節點出現錯誤時,文件系統將失去該節點之下的全部的文件信息。而 ext2/3 卻避免了這種被稱爲」錯誤擴散」的問題。

但不管怎樣,但願您和我同樣,開始認同 btrfs 將是 Linux 將來最有但願的文件系統。

BTRFS 使用簡介

瞭解了 btrfs 的特性,想必您必定想親身體驗一下 btrfs 的使用。本章將簡要介紹如何使用 btrfs 。

建立文件系統

mkfs.btrfs 命令創建一個 btrfs 格式的文件系統。能夠用以下命令在設備 sda5 上創建一個 btrfs 文件系統,並將其掛載到 /btrfsdisk 目錄下:

1
2
3
#mkfs.btrfs /dev/sda5
  #mkdir /btrfsdisk
  #mount – t btrfs /dev/sda5 /btrfsdisk

這樣一個 Btrfs 就在設備 sda5 上創建好了。值得一提的是在這種缺省狀況下,即便只有一個設備,Btrfs 也會對 metadata 進行冗餘保護。若是有多個設備,那麼您能夠在建立文件系統的時候進行 RAID 設置。詳細信息請參見後續的介紹。

這裏介紹其餘幾個 mkfs.btrfs 的參數。

Nodesize 和 leafsize 用來設定 btrfs 內部 BTree 節點的大小,缺省爲一個 page 大小。但用戶也可使用更大的節點,以便增長 fanout,減少樹的高度,固然這隻適合很是大的文件系統。

Alloc-start 參數用來指定文件系統在磁盤設備上的起始地址。這使得用戶能夠方便的預留磁盤前面的一些特殊空間。

Byte-count 參數設定文件系統的大小,用戶能夠只使用設備的一部分空間,當空間不足時再增長文件系統大小。

修改文件系統的大小

當文件系統創建好以後,您能夠修改文件系統的大小。 /dev/sda5 掛載到了 /btrfsdisk 下,大小爲 800M 。假如您但願只使用其中的 500M,則須要減少當前文件系統的大小,這能夠經過以下命令實現:

1
2
3
4
5
6
7
8
9
#df
  Filesystem   1K-blocks     Used      Available   Use%   Mounted on
  /dev/sda1    101086        19000       76867         20%     /boot
  /dev/sda5    811248         32       811216         1%     /btrfsdisk
  #btrfsctl – r -300M /btrfsdisk
  #df
  Filesystem  1K-blocks      Used      Available   Use%   Mounted on
  /dev/sda1    101086        19000       76867         20%     /boot
  /dev/sda5    504148         32       504106         1%     /btrfsdisk

一樣的,您可使用 btrfsctl 命令增長文件系統的大小。

建立 Snapshot

下面的例子中,建立快照 snap1 時系統存在 2 個文件。建立快照以後,對 test1 的內容進行修改。再回到 snap1,打開 test1 文件,能夠看到 test1 的內容依舊是以前的內容。

1
2
3
4
5
6
7
8
9
10
#ls /btrfsdisk
  test1 test2
  #vi test1
  This is a test
  #btrfsctl – s snap1 /btrfsdisk
  #vi test1
  Test1 is modified
  #cd /btrfsdisk/snap1
  #cat test1
  This is a test

能夠從上面的例子看到,快照 snap1 保存的內容不會被後續的寫操做所改變。

建立 subvolume

使用 btrfs 命令,用戶能夠方便的創建 subvolume 。假設 /btrfsdisk 已經掛載到了 btrfs 文件系統,則用戶能夠在這個文件系統內建立新的 subvolume 。好比創建一個 /sub1 的 subvolume,並將 sub1 掛載到 /mnt/test 下:

1
2
3
#mkdir /mnt/test
  #btrfsctl – S sub1 /btrfsdisk
  #mount – t btrfs – o subvol=sub1 /dev/sda5 /mnt/test

Subvolme 能夠方便管理員在文件系統上建立不一樣用途的子文件系統,並對其進行一些特殊的配置,好比有些目錄下的文件關注節約磁盤空間,所以須要打開壓縮,或者配置不一樣的 RAID 策略等。目前 btrfs 尚處於開發階段,建立的 subvolme 和 snapshot 還沒法刪除。此外針對 subvolume 的磁盤 quota 功能也未能實現。但隨着 btrfs 的不斷成熟,這些功能必然將會進一步完善

建立 RAID

mkfs 的時候,能夠指定多個設備,並配置 RAID 。下面的命令演示瞭如何使用 mkfs.btrfs 配置 RAID1 。 Sda6 和 sda7 能夠配置爲 RAID1,即 mirror 。用戶能夠選擇將數據配置爲 RAID1,也能夠選擇將元數據配置爲 RAID1 。

將數據配置爲 RAID1,可使用 mkfs.btrfs 的 -d 參數。以下所示:

1
2
#mkfs.btrfs – d raid1 /dev/sda6 /dev/sda7
 #mount – t btrfs /dev/sda6 /btrfsdisk

添加新設備

當設備的空間快被使用完的時候,用戶可使用 btrfs-vol 命令爲文件系統添加新的磁盤設備,從而增長存儲空間。下面的命令向 /btrfsdisk 文件系統增長一個設備 /sda8

1
#btrfs-vol – a /dev/sda8 /btrfsdisk

SSD 支持

用戶可使用 mount 參數打開 btrfs 針對 SSD 的優化。命令以下:

1
#mount – t btrfs – o SSD /dev/sda5 /btrfsdisk

開啓壓縮功能

用戶可使用 mount 參數打開壓縮功能。命令以下

1
#mount – t btrfs – o compress /dev/sda5 /btrfsdisk

同步文件系統

爲了提升效率,btrfs 的 IO 操做由一些內核線程異步處理。這使得用戶對文件的操做並不會當即反應到磁盤上。您能夠作一個實驗,在 btrfs 上建立一個文件後,稍等 5 到 10 秒將系統電源切斷,再次重啓後,新建的文件並無出現。

對於多數應用這並非問題,但有些時候用戶但願 IO 操做當即執行,此時就須要對文件系統進行同步。下面的 btrfs 命令用來同步文件系統:

1
#btrfsctl – c /btrfsdisk

Debug 功能

Btrfs 提供了必定的 debug 功能,對於想了解 Btrfs 內部實現原理的讀者,debug 將是您最喜歡的工具。這裏簡單介紹一下 debug 功能的命令使用。

下面的命令將設備 sda5 上的 btrfs 文件系統中的元數據打印到屏幕上。

1
#btrfs-debug-tree /dev/sda5

經過對打印信息的分析,您將能瞭解 btrfs 內部各個 BTree 的變化狀況,從而進一步理解每個文件系統功能的內部實現細節。

好比您能夠在建立一個文件以前將 BTree 的內容打印出來,建立文件後再次打印。經過比較兩次的不一樣來了解 btrfs 建立一個文件須要修改哪些元數據。進而理解 btrfs 內部的工做原理。

結束語

我想,在將來的日子裏,EXT 等傳統文件系統確定不會消失。古典文件系統成熟,穩定,經受了歷史的考驗,必然將在很長一段時間內被繼續普遍使用。古典文件系統和新一代文件系統同時並存是很是合理的事情。正如咱們在被陳亦迅的歌聲觸動和感傷以後,還能夠在莫扎特的奏鳴曲中獲得慰藉和平靜。

本人水平有限,對文件系統的瞭解也並不深刻,所以文中必然有不少錯誤的地方,但願能獲得你們的指正。

相關主題

相關文章
相關標籤/搜索