在實際硬體環境中使用 ZFS 需要額外的儲存裝置,例如外接硬碟或 USB 隨身碟。切記不要在 Raspberry Pi 的系統分割區上建立 ZFS 儲存池,以免造成系統無法啟動。確認儲存裝置的邏輯裝置名稱非常重要,可以使用 ls /dev 命令或 Gparted 工具來檢視。以下範例將使用模擬的磁碟檔案來示範 ZFS 的基本操作,避免操作失誤影響實際資料。透過這些範例,讀者可以逐步瞭解 ZFS 的核心概念和使用方法,並為後續的進階應用打下堅實的基礎。

ZFS 管理與應用

在 Raspberry Pi 上使用 ZFS,首先需要將硬碟連線到系統上。接著,在 zpool 中建立一個或多個檔案系統。然後,將檔案新增到檔案系統中。最後,使用適當的 ZFS 命令管理檔案、檔案系統、zpools 和 vdevs。在 Raspberry Pi 系統上使用 ZFS 的工作,就是有效且輕鬆地管理具有「對映」到其上的 vdevs 的 zpools,然後在這些 zpools 中管理檔案系統及其檔案。

圖 1.1 顯示了檔案、資料集(檔案系統)、池和磁碟之間的關係。池 1 有兩個磁碟對映到它上面,並且有一個包含多個檔案的資料集。池 2 有單個磁碟對映到它上面,並且有一個資料集在其中。這種檔案和資料集、池和磁碟的分層結構是 ZFS 的基本結構。

重要的 ZFS 概念

以下是一些非常重要的概念:

  1. vdev 對映限制: 每個 vdev 只能對映或關聯到一個 zpool。因此,如果你想在物理介質(如硬碟或其切片)上建立 zpool,則不能將其他現有的活動 zpool 對映到該 vdev。

  2. vdev 型別: ZFS 支援七種型別的 vdev:

    • 磁碟(預設):系統中的實體硬碟,通常是整個磁碟或主要切片。
    • 檔案:預分配檔案/映像的絕對路徑,類別似於範例 1.1 中的章節 1.2.2。
    • 映象:標準軟體 RAID1 映象。
    • RAID-Z1/2/3:非標準分散式奇偶校驗軟體 RAID 層級。
    • 備用:標記為 ZFS 軟體 RAID 的熱備用硬碟。
    • 快取:用於 Level-2 自適應讀取快取(L2ARC)的裝置。
    • 日誌:稱為 ZFS 操作日誌(ZIL)的單獨日誌(SLOG)。
  3. 預設掛載點: 不同於傳統檔案系統,其中檔案系統的掛載點從特定邏輯驅動器字母開始,zpool 的預設掛載點是根目錄(/``)。

    假設有一個名為 data1 的 zpool,其中有一個名為 bob 的檔案系統,該檔案系統中有一個名為 test.txt 的檔案。這個檔案的路徑會顯示為 /data1/bob/test.txt

  4. 擴充套件 zpool: 在傳統檔案系統中,如 Windows 上的路徑 C:\Users\Robert\Desktop\test.txt。當你希望 ZFS 檔案系統擴充套件到多個磁碟時,可以將更多磁碟新增到 zpool 中。而與傳統 RAID 不同的是,zpool 可以透過新增更多裝置來擴充套件大小,但目前無法縮小大小。

基本 ZFS 池和檔案系統範例:使用 zpool 和 zfs 命令

玄貓在這裡強調一些重要觀點:

  • 在非練習用途下使用 ZFS 需要額外的儲存媒體或裝置連線到硬體上。例如 Raspberry Pi 系統中的外部掛載 USB3 SATA 快速硬碟、PCIe NVMe 媒體或 USB 快閃磁碟。

  • 請注意,不要在 Raspberry Pi 的系統/啟動媒體上建立 zpools,這會使該媒體無法啟動!

建立 zpool 與禁忌操作

以下是一些不應該執行的命令範例:

$ sudo zpool create test /dev/mmcblk0p1
invalid vdev specification
use ‘-f’ to override the following errors:
/dev/mmcblk0p1 does not contain an EFI label but it may contain partition information in the MBR.
$ sudo zpool create test /dev/sda1
invalid vdev specification
use ‘-f’ to override the following errors:
/dev/sda1 contains a filesystem of type ‘ext4’

強制執行上述命令中的任何一個都會使 Raspberry Pi OS 的啟動/系統媒體無法啟動。

查詢已安裝媒體的邏輯裝置名稱

瞭解如何迅速確定當前已安裝且可用媒體的邏輯裝置名稱非常重要。

方法如下:

  1. 切換工作目錄到 /dev
  2. 執行 ls 命令。

如果從 microSD 卡執行你的系統,它會顯示為 mmcblk0,而分割槽則顯示為 mmcblk0p1 等。外部掛載的 USB 媒體(如 USB3 掛載的 SSD 驅動器)則會顯示為 sdasdb 等。第一個分割槽或分割槽的完整路徑指定為 /dev/sda1

你也可以使用 Gparted 分割槽編輯器(如果已安裝),這是一個 GUI 應用程式來檢視所有可用媒體及其邏輯裝置名稱。

基本 ZFS 範例

這裡提供六個介紹性範例來展示如何使用 ZFS 操作。

範例 1.1:使用 zpool 命令:以檔案代替磁碟作為 vdevs

目標:介紹 zpool 命令,並展示使用檔案代替實際磁碟作為 vdevs 的形式。

簡介:如先前所定義的那樣,vdevs 可以是實體裝置(如磁碟驅動器)、檔案、硬碟驅動器上的單一切片或裝置集合。在開始使用實際物理裝置之前,我們將建立並操作重要 ZFS 命令所需的一些檔案來練習使用 ZFS。

以下是範例步驟:

前置條件:
  • 在 Raspberry Pi 上安裝 ZFS。
  • 擁有 root 暨其密碼。
流程:

假設現在成為 root 使用者並建立四個各為 128 MB 的檔案(這些檔案至少需要 64 MB):

root@raspberrypi:~# truncate --size 128m /home/bob/disk1
root@raspberrypi:~# truncate --size 128m /home/bob/disk2
root@raspberrypi:~# truncate --size 128m /home/bob/disk3
root@raspberrypi:~# truncate --size 128m /home/bob/disk4

範例內容解密:

  • 上述命令建立四個各自大小為 128 MB 的空白檔案;這些檔案將被用來模擬 vdevs。
  • 在這些步驟中需要 root 許可權才能完成相關操作。
  • 本範例展示瞭如何利用現有檔案來實踐使用 ZFS 操作功能。
  • 使用者必須小心執行每一步驟以避免錯誤發生;如果發生錯誤可參考範例結尾處列出之清理步驟重新開始。

這樣就完成了介紹性範例中的基本步驟。下面我們繼續深入瞭解其他功能與應用。

ZFS 操作與管理:從基本概念到實際應用

ZFS(Zettabyte File System)是一種強大且靈活的檔案系統,廣泛應用於伺服器和儲存系統中。它提供了高效的資料管理、資料完整性檢查及容錯能力。以下是玄貓(BlackCat)對於 ZFS 的操作與管理的深度分析,結合實際案例與技術選型考量。

操作 ZFS 儲存池

首先,讓我們來看看如何在一個已存在的檔案系統中模擬磁碟並建立 ZFS 儲存池。

1. 建立模擬磁碟

使用 truncate 命令可以快速建立指定大小的檔案來模擬磁碟。以下是建立四個各 128M 的模擬磁碟:

truncate --size 128m /home/bob/disk3
truncate --size 128m /home/bob/disk4

這些檔案將會被當作磁碟來使用。

2. 檢查現有的儲存池

在建立新的儲存池之前,先確認沒有其他儲存池已經存在,以避免混淆:

zpool list

如果沒有現有的儲存池,則會顯示「no pools available」。

3. 建立單一磁碟儲存池

使用 zpool create 命令可以建立一個新的儲存池。這裡我們使用 /home/bob/disk1 作為儲存池中的唯一磁碟:

zpool create data /home/bob/disk1

建立完成後,可以使用 zpool list 命令來檢視現有的儲存池:

NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
data 112M 104K 112M - 2% 0% 1.00x ONLINE -

4. 在新儲存池中建立檔案

接下來,在新建立的 data 儲存池中建立一個檔案並檢查其大小:

truncate --size 32m /data/datafile
ls -lh /data/datafile

在這裡,我們創造了一個大小為 32M 的檔案。

5. 銷毀儲存池

如果需要銷毀某個儲存池,可以使用 zpool destroy 命令:

zpool destroy data

然後再次使用 zpool list 檢查現有的儲存池:

sudo zpool list

應該會顯示「No pools available」。

建立鏡射儲存池

單一磁碟的儲存池並不具備容錯能力,為了提供更好的資料保護,我們可以建立鏡射儲存池。

建立鏡射儲存池

使用兩個磁碟來建立鏡射儲存池:

zpool create data2 mirror /home/bob/disk1 /home/bob/disk2

這樣,data2 池中的資料會被鏡射到兩個磁碟上。

檢查鏡射儲存池狀態

使用 zpool status 命令來檢視 data2 池的詳細狀態:

zpool status data2

此圖示展示了鏡射儲存池的狀態:

  graph TD;
    A[data2] --> B[mirror-0];
    B --> C[/home/bob/disk1];
    B --> D[/home/bob/disk2];
內容解密:

上述圖示展示了 data2 鏡射儲存池的結構,其中包含一個 mirror-0 鏡射組,該組包含兩個磁碟 /home/bob/disk1/home/bob/disk2

在這個鏡射組中,資料會被複製到兩個磁碟上,以提供資料保護功能。當某一磁碟故障時,另一磁碟仍能提供資料讀取和寫入服務。

測試容錯能力

為了測試鏡射儲存池的容錯能力,我們可以故意損壞其中一個磁碟並觀察其反應。

損壞磁碟並進行檢查

使用 dd 命令將隨機資料寫入 /home/bob/disk1 ,模擬磁碟損壞:

dd if=/dev/random of=/home/bob/disk1 bs=512 count=1

然後強制進行一次 scrub 檢查:

zpool scrub data2

接著再次檢查 data2 池的狀態:

zpool status data2

此時應該會顯示某個磁碟為 UNAVAIL(不可用)。

內容解密:

上述操作是模擬磁碟故障的一種方法。透過將隨機資料寫入磁碟標籤,使 ZFS 認為該磁碟已經損壞。接著透過 scrub 檢查來確認資料完整性。最後再次檢查 data2 池的狀態,以確認哪些磁碟已經不可用。這樣可以幫助我們評估 ZFS 在面對硬體故障時的處理能力及其對資料保護的效果。

故障還原與維護

當某個鏡射組中的一個磁碟損壞後,我們需要進行故障還原操作。

分離故障磁碟

首先,分離故障的 /home/bob/disk1

zpool detach data2 /home/bob/disk1

然後再次檢查 data2 池的狀態:

zpool status data2

應該只剩下 /home/bob/disk2 一個可用磁碟。

新增新磁碟

刪除故障的 /home/bob/disk1 檔案後重新建立:

rm /home/bob/disk1
truncate --size 128m /home/bob/disk1

接著將新建立的 /home/bob/disk1 增加回鏡射組中:

zpool attach data2 /home/bob/disk2 /home/bob/disk1

最後再次檢查 data2 池的狀態來確認還原成功:

zpool status data2

此時應該顯示兩個磁碟均為 ONLINE(正常)。

加入新硬碟至鏡射儲存池

ZFS 的一大優勢是可以在不需要停機或線上狀態下增加硬碟至已存在之鏡射群組。以下是如何雙倍增加我們之 data2 池容量。

首先先確認目前之 pool 資訊:

zpool status data2

# 在 output 中看到目前 pool 的 mirror-0 包含兩塊硬碟: / home/ bob/ disk1, / home/ bob/ disk3, 分別相同大小.

我們可以選擇增加第二個 mirror group:

# 創造第二組 mirror group: (disk4, disk5)
# 建議以相同大小硬碟創造第二組 mirror group, 不然可能會有分配問題.
truncate --size 128m /home/bob/disk4 # 創造第一塊硬碟: disk4, 大小為 16MB.
truncate --size 16m /home/bob/disk5 # 創造第二塊硬碟: disk5, 大小為 3MB.

接著將新創造之二塊硬碟加入到 pool 中:

# 新增第二組 mirror group: disk4, disk5.
# zpool add 命令是指定要加入 pool 的 harddisk, 錯誤指定 harddisk 或 size 不同時可能造成分配問題.
# 加入之前應該確認要加入 pool 的 harddisk 是否有相同大小.
zpool add data2 mirror / home/ bob/ disk4 / home/ bob/ disk5 # 啟動命令後應該可以觀察到 zfs 在進行 resilvering...
# resilvering 是 ZFS 的功能之一, 能夠讓 user 能夠在不中斷服務之下進行硬體升級或替換硬體.
# resilvering 是指 ZFS 調整 existing harddisk 中內容與組態, 原本內容重新分配到新加入 harddisk 中.
# resilvering 有點類別似於 RAID 中 rebuild 的功能, 和 RAID rebuild 不同的是: RAID rebuild 在進行中的時間無法讀取寫入,
# 不過 ZFS resilvering 是可以在進行過程中讀取寫入 harddisk 中內容.

最後確認 pool 資訊:

# 執行以下命令之後:
ls -lh /

在此例中觀察到目前 pool 左右總共有二組 mirror group, 第一組為 (disk3,disk5) 第二組為 (disk4,disk5), 每組皆為大小相同且都是獨立運作之分散式原子處理群組.

內容解密:

上述操作展示瞭如何線上上狀態下向現有之鏡射群組內加入新硬碟, 作法原理是將原本已存在之 harddisk 與新增之 harddisk 分成不同 group, 重複過去分配內容進行 resilvering 調整內部邏輯與組態等動作, 新增成功後整體之 pool 左右將會再增加一組 mirror group.