# 在Ubuntu 20.04 安裝 ZFS 檔案系統 ###### tags: `Linux`, `ZFS` ## 前言 本來想在舊電腦上跑 mdadm 做軟RAID,但說實在只有一些基礎的功能。在 QNAP 品牌NAS上跑的軟體陣列也是用ZFS,具有可使用SSD當快取、重建速度較快等優點,因此本文將著重在記錄如何利用ZFS建立RAID。 | 項目 | 說明 | | --------------|:----------------------- | | Device Support| HDD、SSD、NVMe | | RAID | 支援更多模式的軟RAID | | Hot Spare | ZFS軟RAID的熱插拔 | | Cache | level 2 adaptive read cache(ZFS L2ARC)| | Log | ZFS Intent Log (ZFS ZIL) | | Snapshot | ZFS 快照功能 | ## 環境 ubuntu 20.04 LTS kernel 5.8.0-59-generic ## 安裝 皆在root權限下處理 ```linux= apt install zfsutils-linux ``` 確認是否有安裝成功 ```linux= whereis zfs zfs: /usr/sbin/zfs /etc/zfs /usr/share/man/man8/zfs.8.gz ``` 利用 ```lsblk``` 確認要加入ZFS pool的硬碟是哪幾顆 ![](https://i.imgur.com/Vdj2x7s.png) 我這邊要用sda、sdc、sdd、sde 做 RAID10,sdf做備援 (hot spare),sdb做快取 問題來了,在ZFS中如何做到RAID呢 ? ## VDEV in ZFS zpool 是在ZFS中的儲存單位,可以將多個實體硬碟丟進一個zpool內做存取。 VDEV 則是指在ZFS中的虛擬裝置,可以想成是pool的概念。 可以用以下指令查詢zpool 的狀態 ```linux= zpool status ``` 解除 ```linux= zpool destroy <pool name> ``` ### Striped VDEVS 相當等於RAID 0,建立了一個pool叫pool-test 其中包含了 /dev/sda、/dev/sdc、/dev/sdd ```linux= zpool create pool-test /dev/sda /dev/sdc /dev/sdd ``` 查看 ```linux= zpool status pool-test ``` 解除 ```linux= zpool destroy pool-test ``` ### Mirrored VDEVs 相當於RAID0,鏡像可以是2顆(含)以上的硬碟 在參數內加入mirror ```linux= zpool create pool-test mirror /dev/sda /dev/sdc /dev/sdd ``` ### Striped Mirrored VDEVs 顧名思義,這就是如同RAID10的概念 ```linux= zpool create pool-test mirror /dev/sda /dev/sdc mirror /dev/sdd /dev/sde ``` or ```linux= zpool create pool-test mirror /dev/sda /dev/sdc zpool add pool-test mirror /dev/sdd /dev/sde ``` ### RAIDZ 相當於RAID 5,允許1個硬碟失效,最低需要4個硬碟 ```linux= zpool create pool-test raidz /dev/sda /dev/sdc /dev/sdd /dev/sde ``` ### RAIDZ2 相當於RAID 6,允許2個硬碟失效,最低需要5個硬碟 ```linux= zpool create pool-test raidz2 /dev/sda /dev/sdc /dev/sdd /dev/sde /dev/sdf ``` ### RAIDZ3 允許3個硬碟失效,最低需要6個硬碟,效能與RAIDZ與RAIDZ2相當 ```linux= zpool create pool-test raidz3 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg ``` ### Nested RAIDZ 相當於 RAID50、RAID60、striped RAIDZ,可利用空間有所減少,但效能比RAIDZ好 striped RAIDZ範例 (2X RAIDZ): ```linux= zpool create pool-test raidz /dev/sdb /dev/sdc /dev/sdd /dev/sde zpool add pool-test raidz /dev/sdf /dev/sdg /dev/sdh /dev/sdi ``` ## Log ZFS中的logging mechanism稱作ZIL,用以紀錄data跟metadata儲存的位置 常會使用SSD作為ZIL,也可以使用超過1個的SSD ```linux= zpool add pool-test log /dev/sdg -f ``` 更多 [detail](http://nex7.blogspot.com/2013/04/zfs-intent-log.html) ## Cache 用以加速隨機讀取 ```linux= zpool add pool-test cache /dev/sdh -f ``` ## Snapshot ZFS snapshot是一個唯讀的複製品。 可用以儲存指定時間點的ZFS檔案系統,並可於之後恢復指定時間點的狀態 甚至可以恢復單一檔案的快照,而不用恢復整個系統,可說是相當方便 假設在pool-test下有一個資料夾project ```linux= zfs snapshot -r pool-test/project@snap1 ``` 查看snapshot ```linux= zfs list -t snapshot ``` 假設現在 /pool-test/project 損壞了 ```linux= rm -rf pool-test/project ``` 恢復 ```linux= zfs rollback pool-test/project@snap1 ``` 移除snapshot ```linux= zfs destroy pool-test/project@snap1 ``` ## Clone clone是指在 ZFS 中從原系統檔案複製出來的複製品,具備可讀寫的特性。 clone只能從snapshot建立,也就是說必須要先有一份snapshot才能建立clone,而那份snapshot在clone被刪掉前是無法刪除的。 建立snapshot ```linux= zfs snapshot -r pool-test@snap1 ``` 從 /pool-test/project 建立clone ```linux= zfs clone pool-test/project@snap1 pool-test/project-clone ``` ## ZFS 傳送與接收 如果我們建立了ZFS file system的snapshot,但總要把snapshot放在別的地方,例如google雲端做備份吧,免得硬碟壞掉snapshot一起不見。因此此功能是將ZFS的snapshot建立成檔案,使其可以傳送到他處,同時也可以接收來自他處的snapshot檔,並以其作為snapshot恢復系統。 建立 snaphsot 並把其存成檔案 ```linux= zfs snapshot -r pool-test/project@snap2 zfs send pool-test/project@snap2 > ~/project-snap2.zfs ``` 從 snapshot 檔恢復成 snapshot 到 /pool-test/project-copy ```linux= zfs receive -F pool-test/project-copy < ~/project-snap2.zfs ``` ## ZFS Ditto Blocks Ditto指的是百變怪...不是啦,是指ZFS中提供更多的複製功能,可以選擇將指定資料/資料夾複製更多份在約1/8個磁區處(一個硬碟時),或是在VDEVs(多個硬碟時)中。這個功能可以提供在硬碟壞軌時的保障,但無法做到如 RAIDZ 層等級的保護。 建立百變怪區塊,copy數量可以選擇1~3。 ```linux= zfs set copies=3 pool-test/project ``` 查看copy資訊 ```linux= zfs get copies pool-test/project ``` ## ZFS compression 在現今CPU性能日益強悍的情況下,ZFS提供的壓縮功能更具價值。 透過壓縮檔案大小,代表了更小的硬碟讀取頭移動範圍,因此加速了I/O。 壓縮種類具有gzip-9、lz4等,因為lz4具有相當強的效能,因此預設也是lz4。 ```linunx= zfs set compression=lz4 pool-test ``` check ```linux= zfs get compressration ``` ## 結論 所以回到問題,我的目標是:用sda、sdc、sdd、sde 做 Striped Mirrored VDEVs (RAID10),sdf做備援 (hot spare)且開啟動態替換功能,sdb做快取,並且開啟ZFS壓縮功能。 ```linux= zpool create pool-test mirror /dev/sda /dev/sdc mirror /dev/sdd /dev/sde spare /dev/sdf zpool add pool-test cache /dev/sdb -f zpool set autoreplace=on pool-test zfs set compression=lz4 pool-test ``` check ```linux= zfs get all pool-test ``` 除了在硬碟使用ZFS之外,系統碟也支援ZFS,可以在建立系統時就設定好 [Ubuntu 20.04 Root on ZFS](https://openzfs.github.io/openzfs-docs/Getting%20Started/Ubuntu/Ubuntu%2020.04%20Root%20on%20ZFS.html),也可以 [利用MAAS設定](https://ubuntu.com/blog/deploying-ubuntu-root-on-zfs-with-maas)。 ZFS是一個相當強大的檔案管理系統,具有許多管理與備份功能 ## Reference & More https://linuxhint.com/installing_zfs_ubuntu_20-04/ https://wiki.ubuntu.com/Kernel/Reference/ZFS http://cloverhsc.blogspot.com/2013/12/zfs-vdev-3.html https://docs.oracle.com/cd/E19253-01/819-5461/6n7ht6qr7/index.html https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Workload%20Tuning.html https://docs.freebsd.org/zh-tw/books/handbook/zfs/ http://manpages.ubuntu.com/manpages/focal/man8/zpool.8.html ## Others [Guide to setting up ZED to e-mail alerts for ZFS on Proxmox](https://www.reddit.com/r/homelab/comments/8c09pr/guide_to_setting_up_zed_to_email_alerts_for_zfs/) Note: 其中密碼的部份需用Google->帳戶->安全性->應用程式密碼中建立的16位密碼取代 [Test ZED Notification Emails](https://www.reddit.com/r/zfs/comments/fb8utq/how_to_test_zed_notification_emails/)