---
# System prepended metadata

title: 在Ubuntu 20.04 安裝 ZFS 檔案系統
tags: [Linux, ZFS]

---

# 在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/)


