19.8. ZFS 特色與術語

ZFS 是一個從本質上與眾不同的檔案系統,由於它並非只是一個檔案系統,ZFS 結合了檔案系統及磁碟區管理程式,讓額外的儲存裝置可以即時的加入到系統並可讓既有的檔案系統立即使用這些在儲存池中空間。透過結合傳統區分為二的兩個角色,ZFS 能夠克服以往 RAID 磁碟群組無法擴充的限制。每個在儲存池頂層的裝置稱作 vdev,其可以是一個簡單的磁碟或是一個 RAID 如鏡像或 RAID-Z 陣列。ZFS 的檔案系統 (稱作 資料集 (Dataset)) 每一個資料集均可存取整個存池所共通的可用空間,隨著使用儲存池來配置空間區塊,儲存池能給每個檔案系統使用的可用空間就會減少,這個方法可以避免擴大分割區會使的可用空間分散分割區之間的常見問題。

儲存池 (Pool)A storage pool is the most basic building block of ZFS. A pool is made up of one or more vdevs, the underlying devices that store the data. A pool is then used to create one or more file systems (datasets) or block devices (volumes). These datasets and volumes share the pool of remaining free space. Each pool is uniquely identified by a name and a GUID. The features available are determined by the ZFS version number on the pool.
vdev 型態 (vdev Types)儲存池是由一個或多個 vdev 所組成,vdev 可以是一個磁碟或是 RAID Transform 的磁碟群組。當使用多個 vdev,ZFS 可以分散資料到各個 vdev 來增加效能與最大的可用空間。
  • 磁碟 (Disk) - 最基本的 vdev 型態便是一個標準的資料區塊裝置,這可以是一整個磁碟 (例如 /dev/ada0/dev/da0) 或一個分割區 (/dev/ada0p3)。在 FreeBSD 上,使用分割區來替代整個磁碟不會影響效能,這可能與 Solaris 說明文件所建議的有所不同。

  • 檔案 (File) - 除了磁碟外,ZFS 儲存池可以使用一般檔案為基礎,這在測試與實驗時特別有用。在 zpool create 時使用檔案的完整路徑作為裝置路徑。所有 vdev 必須至少有 128 MB 的大小。

  • 鏡像 (Mirror) - 要建立鏡像,需使用 mirror 關鍵字,後面接著要做為該鏡像成員裝置的清單。一個鏡像需要由兩個或多個裝置來組成,所有的資料都會被寫入到所有的成員裝置。鏡像 vdev 可以對抗所有成員故障只剩其中一個而不損失任何資料。

    注意:

    正常單一磁碟的 vdev 可以使用 zpool attach 隨時升級成為鏡像 vdev。

  • RAID-Z - ZFS 實作了 RAID-Z,以標準的 RAID-5 修改而來,可提供奇偶校驗 (Parity) 更佳的分散性並去除了 RAID-5 write hole 導致在預期之外的重啟後資料與奇偶校驗資訊不一致的問題。ZFS 支援三個層級的 RAID-Z,可提供不同程度的備援來換取減少不同程度的可用空間,類型的名稱以陣列中奇偶校驗裝置的數量與儲存池可以容許磁碟故障的數量來命名,從 RAID-Z1RAID-Z3

    RAID-Z1 配置 4 個磁碟,每個磁碟 1 TB,可用的儲存空間則為 3 TB,且若其中一個磁碟故障仍可以降級 (Degraded) 的模式運作,若在故障磁碟尚未更換並修復 (Resilver) 之前又有磁碟故障,所有在儲存池中的資料便會遺失。

    RAID-Z3 配置 8 個 1 TB 的磁碟,磁碟區將會可以提供 5 TB 的可用空間且在 3 個磁碟故障的情況下仍可運作。Sun™ 建議單一個 vdev 不要使用超過 9 個磁碟。若配置需要使用更多磁碟,建議分成兩個 vdev,這樣儲存池的資料便會分散到這兩個 vdev。

    使用兩個 RAID-Z2 各由 8 個磁碟組成的 vdev 的配置可以建立一個類似 RAID-60 的陣列。RAID-Z 群組的儲存空量會接近其中最小的磁碟乘上非奇偶校驗磁碟的數量。4 個 1 TB 磁碟在 RAID-Z1 會有接近 3 TB 的實際大小,且一個由 8 個 1 TB 磁碟組成的 RAID-Z3 陣列會有 5 TB 的可用空間。

  • 備援 (Spare) - ZFS 有特殊的虛擬 vdev 型態可用來持續追蹤可用的熱備援裝置 (Hot spare)。注意,安裝的熱備援裝置並不會自動佈署,熱備援裝置需要手動使用 zfs replace 設定替換故障的裝置。

  • 日誌 (Log) - ZFS 記錄裝置,也被稱作 ZFS 意圖日誌 (ZFS Intent Log, ZIL) 會從正常的儲存池裝置移動意圖日誌到獨立的裝置上,通常是一個 SSD。有了獨立的日誌裝置,可以明顯的增進有大量同步寫入應用程式的效能,特別是資料庫。日誌裝置可以做成鏡像,但不支援 RAID-Z,若使用多個日誌裝置,寫入動作會被負載平衡分散到這些裝置。

  • 快取 (Cache) - 加入快取 vdev 到儲存池可以增加儲存空間的 L2ARC 快取。快取裝置無法做鏡像,因快取裝置只會儲存額外的現有資料的複本,並沒有資料遺失的風險。

交易群組 (Transaction Group, TXG)交易群組是一種將更動的資料區塊包裝成一組的方式,最後再一次寫入到儲存池。交易群組是 ZFS 用來檢驗一致性的基本單位。每個交易群組會被分配一個獨一無二的 64-bit 連續代號。最多一次可以有三個活動中的交易群組,這三個交易群組的每一個都有這三種狀態:
  • 開放 (Open) - 新的交易群組建立之後便處於開放的狀態,可以接受新的寫入動作。永遠會有開放狀態的交易群組,即始交易群組可能會因到達上限而拒絕新的寫入動作。一但開放的交易群組到達上限或到達 vfs.zfs.txg.timeout,交易群組便會繼續進入下一個狀態。

  • 靜置中 (Quiescing) - 一個短暫的狀態,會等候任何未完成的操作完成,不會阻擋新開放的交易群組建立。一旦所有在群組中的交易完成,交易群組便會進入到最終狀態。

  • 同步中 (Syncing) - 所有在交易群組中的資料會被寫任到穩定的儲存空間,這個程序會依序修改其他也需同樣寫入到穩定儲存空間的資料,如 Metadata 與空間對應表。同步的程多會牽涉多個循環,首先是同步所有更改的資料區塊,也是最大的部份,接著是 Metadata,這可能會需要多個循環來完成。由於要配置空間供資料區塊使用會產生新的 Metadata,同步中狀態在到達循環完成而不再需要分配任何額外空間的狀態前無法結束。同步中狀態也是完成 synctask 的地方,Synctask 是指管理操作,如:建立或摧毀快照與資料集,會修改 uberblock,也會在此時完成。同步狀態完成後,其他處於狀態中狀態的交易群組便會進入同步中狀態。

所有管理功能如快照 (Snapshot) 會作為交易群組的一部份寫入。當 synctask 建立之後,便會加入到目前開放的交易群組中,然後該群組會盡快的進入同步中狀態來減少管理指令的延遲。
Adaptive Replacement Cache (ARC)ZFS 使用了自適應替換快取 (Adaptive Replacement Cache, ARC),而不是傳統的最近最少使用 (Least Recently Used, LRU) 快取,LRU 快取在快取中是一個簡單的項目清單,會依每個物件最近使用的時間來排序,新項會加入到清單的最上方,當快取額滿了便會去除清單最下方的項目來空出空間給較常使用的物件。ARC 結合了四種快取清單,最近最常使用 (Most Recently Used, MRU) 及最常使用 (Most Frequently Used, MFU) 物件加上兩個清單各自的幽靈清單 (Ghost list),這些幽靈清單會追蹤最近被去除的物件來避免又被加回到快取,避免過去只有偶爾被使用的物件加入清單可以增加快取的命中率。同時使用 MRUMFU 的另外一個優點是掃描一個完整檔案系統可以去除在 MRULRU 快取中的所有資料,有利於這些才剛存取的內容。使用 ZFS 也有 MFU 可只追蹤最常使用的物件並保留最常被存取的資料區塊快取。
L2ARCL2ARCZFS 快取系統的第二層,主要的 ARC 會儲存在 RAM 當中,但因為 RAM 可用的空間量通常有限,因此 ZFS 也可以使用 快取 vdev (Cache vdev)。固態磁碟 (Solid State Disk, SSD) 常被拿來此處作為快取裝置,因為比起傳統旋轉碟片的磁碟,固態磁碟有較快的速度與較低的延遲。L2ARC 是選用的,但使用可以明顯增進那些已使用 SSD 快取的檔案讀取速度,無須從一般磁碟讀取。L2ARC 也同樣可以加速去重複 (Deduplication),因為 DDT 並不適合放在 RAM,但適合放在 L2ARC,比起要從磁碟讀取,可以加快不少速度。為了避免 SSD 因寫入次速過多而過早耗損,加入到快取裝置的資料速率會被限制,直到快取用盡 (去除第一個資料區塊來騰出空間) 之前,寫入到 L2ARC 的資料速率會限制在寫入限制 (Write limit) 與加速限制 (Boost limit) 的總合,之後則會限制為寫入限制,可以控制這兩個速度限制的 sysctl(8) 數值分別為 vfs.zfs.l2arc_write_max 控制每秒有多少數位元組可寫入到快取,而 vfs.zfs.l2arc_write_boost 可在 渦輪預熱階段 (即寫入加速) 時增加寫入限制。
ZILZIL 會使用比主要儲存池還更快的儲存裝置來加速同步寫入動作 (Synchronous transaction),如 SSD。當應用程式請求做一個同步的寫入時 (保証資料會安全的儲存到磁碟,而不是先快取稍後再寫入),資料會先寫入到速度較快的 ZIL 儲存空間,之後再一併寫入到一般的磁碟。這可大量的減少延遲並增進效能。ZIL 只會有利於使用像資料庫這類的同步工作,一般非同步的寫入像複製檔案,則完全不會用到 ZIL
寫入時複製 (Copy-On-Write)不像傳統的檔案系統,在 ZFS,當資料要被覆寫時,不會直接覆寫舊資料所在的位置,而是將新資料會寫入到另一個資料區塊,只在資料寫入完成後才會更新 Metadata 指向新的位置。因此,在發生寫入中斷 (在寫入檔案的過程中系統當機或電源中斷) 時,原來檔案的完整內容並不會遺失,只會放棄未寫入完成的新資料,這也意謂著 ZFS 在發生預期之外的關機後不需要做 fsck(8)
資料集 (Dataset)資料集 (Dataset)ZFS 檔案系統、磁碟區、快照或複本的通用術語。每個資料集都有獨一無二的名稱使用 poolname/path@snapshot 格式。儲存池的根部技術上來說也算一個資料集,子資料集會採用像目錄一樣的層級來命名,例如 mypool/home,home 資料集是 mypool 的子資料集並且會繼承其屬性。這可以在往後繼續擴展成 mypool/home/user,這個孫資料集會繼承其父及祖父的屬性。在子資料集的屬性可以覆蓋預設繼承自父及祖父的屬性。資料集及其子資料級的管理權限可以委託 (Delegate) 給他人。
檔案系統 (File system)ZFS 資料集最常被當做檔案系統使用。如同大多數其他的檔案系統,ZFS 檔案系統會被掛載在系統目錄層級的某一處且內含各自擁有權限、旗標及 Metadata 的檔案與目錄。
磁碟區 (Volume)除了一般的檔案系統資料集之外,ZFS 也可以建立磁碟區 (Volume),磁碟區是資料區塊裝置。磁碟區有許多與資料集相似的功能,包含複製時寫入、快照、複本以及資料校驗。要在 ZFS 的頂層執行其他檔案系統格式時使用磁碟區非常有用,例如 UFS 虛擬化或匯出 iSCSI 延伸磁區 (Extent)。
快照 (Snapshot)ZFS 的寫入時複製 (Copy-On-Write, COW) 設計可以使用任意的名稱做到幾乎即時、一致的快照。在製做資料集的快照或父資料集遞迴快照 (會包含其所有子資料集) 之後,新的資料會寫入到資的資料區塊,但不會回收舊的資料區塊為可用空間,快照中會使用原版本的檔案系統,而快照之後所做的變更則會儲存在目前的檔案系統,因此不會重複使用額外的空間。當新的資料寫入到目前的檔案系統,便會配置新的資料區塊來儲存這些資料。快照表面大小 (Apparent size) 會隨著在目前檔案系統停止使用的資料區塊而成長,但僅限於快照。可以用唯讀的方式掛載這些快照來復原先前版本的檔案,也可以還原 (Rollback) 目前的檔案系統到指定的快照,來還原任何在快照之後所做的變更。每個在儲存池中的資料區塊都會有一個參考記數器,可以用來持續追蹤有多少快照、複本、資料集或是磁碟區使用這個資料區塊,當刪除檔案與快照參照的計數變會滅少,直到沒有任何東西參考這個資料區塊才會被回收為可用空間。快照也可使用 hold 來標記,檔標記為 hold 時,任何嘗試要刪除該快照的動作便會回傳 EBUSY 的錯誤,每個快照可以標記多個不同唯一名稱的 hold,而 release 指令則可以移除 hold,這樣才可刪除快照。在磁碟區上快可以製作快照,但只能用來複製或還原,無法獨立掛載。
複本 (Clone)快照也可以做複本,複本是可寫入版本的快照,讓檔案系統可分支成為新的資料集。如同快照,複本一開始不會消耗任何額外空間,隨著新資料寫入到複本會配置新的資料區塊,複本的表面大小 (Apparent size) 才會成長,當在複本檔案系統或磁碟區的資料區塊被覆寫時,在先前資料區塊的參考計數則會減少。建立複本所使用的快照無法被刪除,因為複本會相依該快照,快照為父,複本為子。複本可以被提升 (promoted)、反轉相依關係,來讓複本成為父,之前的父變為子,這個操作不需要額外的空間。由於反轉了父與子使用的空間量,所以可能會影響既有的配額 (Quota) 與保留空間 (Reservation)。
校驗碼 (Checksum)配置每個資料區塊快的同時也會做資料校驗,資料校驗用的演算法是依資料集屬性而有所不同的,請參考 set。每個資料區塊會在讀取的過成便完成校驗,讓 ZFS 可以偵測到隱藏的損壞,若資料不符合預期的校驗碼,ZFS 會嘗試從任何可用的備援來還原資料,例如鏡像 (Mirror) 或 RAID-Z。要檢驗所有資料的校驗碼可以使用清潔 (Scrub),資料校驗的演算法有:
  • fletcher2

  • fletcher4

  • sha256

fletcher 演算法最快,而 sha256 雖較消耗效能,但其有強大的密碼雜湊與較低的衝突率。也可關閉資料校驗,但並不建議。
壓縮 (Compression)每個資料集都有壓縮 (Compression) 屬性,預設是關閉的,這個屬性可以設定使用以下幾個壓縮演算法的其中一個來壓縮寫入到資料集的新資料。壓縮除了減少空間使用量外,常也會增加讀取與寫入的吞吐量,因為會減少讀取與寫入的資料區塊。
  • LZ4 - ZFS 儲存池版本 5000 (功能旗標) 後所增加,LZ4 現在是建議的壓縮演算法,在處理可壓縮的資料時 LZ4 壓縮比 LZJB 快將近 50%,在處理不可壓縮的資料時快將近三倍,LZ4 解壓縮也比 LZJB 將近 80%。在現代的 CPU 上,LZ4 經常平均可用 500 MB/s 的速度壓縮,而解壓縮可到達 1.5 GB/s (每個 CPU 核心)。

  • LZJB - 預設的壓縮演算法。由 Jeff Bonwick 所開發 (ZFS 的創始人之一)。LZJBGZIP 相比,可以較低的 CPU 提供較佳的壓縮功能。在未來預設的壓縮演算法將會更換為 LZ4

  • GZIP - 在 ZFS 可用的熱門串流壓縮演算法。使用 GZIP 主要的優點之一便是可設定壓縮層級。當設定 compress 屬性,管理者可以選擇壓縮層級範圍從最低的壓縮層級 gzip1 到最高的壓縮層級 gzip9。這讓管理者可以控制要使用多少 CPU 來節省磁碟空間。

  • ZLE - 零長度編號是一個特殊的壓縮演算法,它只會壓縮連續的零。這種壓縮演算法只在資料集中含有大量為零的資料區塊時有用。

備份數 (Copies)當設定大於 1 的數值時,copies 屬性會指示 ZFS 備份每個在檔案系統 (File System) 或磁碟區 (Volume) 的資料區塊數份。在重要的資料集上設定這個屬性可以做額外的備援以在資料校驗碼不相符時可做復原。在沒有做備援的儲存池上,備份功能提供只是一種資料的備援方式,備份功能可以復原單一壞軌或其他情況的次要損壞,但無法復原儲存池中整個磁碟損壞所損失的資料。
去重複 (Deduplication)校驗碼讓在寫入時可以偵測重複資料區塊,使用去重複,可以增加既有、完全相同的資料區塊參考數來節省儲存空間。要偵測重複的資料區塊需要在記憶體中儲存去重複資料表 (Deduplication table, DDT),這個資料表中會有唯一的校驗碼清單、這些資料區塊的所在位置以及參考數。當寫入新資料時,便會計算校驗碼然後比對清單中是否有符合的既有資料區塊已在清單。去重複使用了 SHA256 校驗碼演算法來提供一個安全的加密雜湊,去重複功能是可以調校的,若 dedup 設為 on 只要符合校驗碼便會認為資料完全相同,若 dedup 設為 verify 則會一個一個位元檢查兩個資料區塊的資料來確保資料真的完全相同,若資料不同便會註記與雜湊衝突並會分別儲存兩個資料區塊。由於 DDT 須要儲存每個唯一資料區塊的雜湊,所以會消耗大量的記憶體,一般的經驗法則是每 1 TB 的去重複資料需要使用 5-6 GB 的記憶體。由於要有足夠的 RAM 來儲存整個 DDT 在實務上並不實際,導致在每個新資料區塊寫入前需要從磁碟來讀取 DDT 會對效能有很大的影響,去重複功能可以使用 L2ARC 儲存 DDT 以在快速的系統記憶體及較慢的磁碟之間取得一個平衡點。也可以考慮使用壓縮功能來取代此功能,因為壓縮也能節省相近的空間使用量而不需要大量額外的記憶體。
清潔 (Scrub)ZFSscrub 來替代 fsck(8) 來做一致性的檢查。scrub 會讀取所有儲存在儲存池中的資料區塊並且根據儲存在 Metadata 中已知良好的校驗碼來檢驗這些資料區塊的校驗碼,定期檢查儲存池中儲存的所有資料可以確保實際使用這些資料前已將所有損壞的資料區塊復原。在不正常的關閉之後並不需要做清潔動作,但建議每三個月至少執行一次。在正常使用讀取時便會檢查每個資料區塊的校驗碼,但清潔動作可以確保那些不常用的資料也會被檢查以避免隱藏的損壞,如此便能增進資料的安全性,特別是對用來保存資料的儲存裝置。scrub 可以使用 vfs.zfs.scrub_delay 調整相對優先權來避免清潔動作降低儲存池上其他工作的效率。
資料集配額 (Dataset Quota)除了配額及空間保留外,ZFS 提供非常快速且準確的資料集、使用者及群組空間的計算功能,這可讓管理者調整空間配置的方式且可為重要的檔案系統保留空間。

ZFS supports different types of quotas: the dataset quota, the reference quota (refquota), the user quota, and the group quota.

配額會限制資料集及後裔包含資料集的快照、子資料集及子資料集的快照能使用的空間量。

注意:

磁碟區上無法設定配額,因為 volsize 屬性已經被用來做內定的配額。

參考配額 (Reference Quota)參考配額可以設定一個硬性限制 (Hard limit) 來限制資料集能使用的空間量,而這個硬性限制只包含了資料集參考的空間,並不含其後裔所使用的空間,如:檔案系統或快照。
使用者配額 (User Quota)使用者配額在用來限制特定使用者能使用的空間量時非常有用。
群組配額 (Group Quota)群組配額可以限制特定群組能使用的空間量。
資料集保留空間 (Dataset Reservation)reservation 屬性可以確保對特定資料集及其後裔最小可用的空間量,若在 storage/home/bob 設定 10 GB 的保留空間且其他資料集嘗試使用所有剩餘的空間時,會保留至少 10 GB 的空間供這個資料集使用。若要製作 storage/home/bob 的快照,該快照所使用的空間也會被列入保留空間計算。 refreservation 屬性也以類似的方式運作,但是他 不包含 後裔,例如:快照。

不管那一種保留空間在許多情境皆很有用,例如:要規劃與測試磁碟空間配置在新系統上的適應性,或是確保有足夠的空間供稽查日誌或系統還原程序及檔案使用。

參考保留空間 (Reference Reservation)refreservation 屬性可以確保對特定資料集 不包含 其後裔最小可用的空間,這代表若在 storage/home/bob 設定 10 GB 的保留空間且其他資料集嘗試使用所有剩餘的空間時,會保留至少 10 GB 的空間供這個資料集使用。於正常 reservation 不同的是,由快照及後裔資料集所使用的空間並不會列入保留空間計算。例如,若要製作一個 storage/home/bob 的快照,在 refreservation 空間之外必須要有足夠的空間才能成功完成這項操作,主資料集的後裔並不會列入 refreservation 空間額計算,所以也不會佔用保留空間。
修復 (Resilver)當有磁碟故障且被更換後,新的磁碟必須回存先前所遺失的資料,會使用分散在其他磁碟上的奇偶校驗資訊來計算並寫入遺失的資料到新的磁碟機的這個程序稱作 修復 (Resilvering)
上線 (Online)一個儲存池或 vdev 處於線上 (Online) 狀態時代表所有該裝置的成員均已連結且正常運作。個別裝置處於線上 (Online) 狀態時代表功能正常。
離線 (Offline)若有足夠的備援可避免儲存池或 vdev 進入故障 (Faulted) 狀態,個別裝置若可由管理者設為離線 (Offline) 狀態,管理者可以選擇要設定那一個磁碟為離線來準備更換或是讓其更容易辨識。
降級 (Degraded)一個儲存池或 vdev 處於降級 (Degraded) 狀態代表其有一個或多個磁碟已斷線或故障,此時儲存池仍可以使用,但只要再有其他的裝置故障,儲存池會無法復原。重新連線缺少的裝置或更換故障的磁碟,並在新裝置完成修復 (Resilver) 程序可讓儲存池返回線上 (Online) 狀態。
故障 (Faulted)一個儲存池或 vdev 處於故障 (Faulted) 狀態代表無法運作,會無法存取在該裝置上的資料。當在 vdev 中缺少或故障的裝置數超過備援的層級,儲存池或 vdev 會進入故障 (Faulted) 狀態。若缺少的裝置可以重新連結上,儲存池便會返回線上 (Online) 狀態。若沒有足夠的備援可補償故障的磁碟數量便會遺失儲存池中的內容且只能從備份還原。

本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

若有 FreeBSD 方面疑問,請先閱讀 FreeBSD 相關文件,如不能解決的話,再洽詢 <questions@FreeBSD.org>。

關於本文件的問題,請洽詢 <doc@FreeBSD.org>。