Skip to content

Commit

Permalink
zfs: add some content
Browse files Browse the repository at this point in the history
  • Loading branch information
iBug committed Jul 8, 2024
1 parent a2c62dd commit 3b9f986
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ icon: material/heart

作为 [Linux 101](https://101.lug.ustc.edu.cn) 的进阶版,本教程主要面向**需要了解如何运维少量服务器**的用户,特别是和编者们一样的**学生运维**,因此和其他的教程在编写风格等方面存在不同。Linux 201 采取以下的编写原则:

- Debian First:Debian 是非常稳定可靠的社区 Linux 发行版,同时 USTCLUG 几乎所有的服务器都运行 Debian,因此本教程以 Debian 作为主要参考发行版。当然,其他的发行版也会有所涉及。
- Debian First:Debian 是非常稳定可靠的社区 Linux 发行版,同时 USTCLUG 所有的服务器都运行 Debian,因此本教程以 Debian 作为主要参考发行版。当然,其他的发行版也会有所涉及。
- Linux 201 不是手册的复读机:本教程不会详细介绍所有软件的每个细节。作为一项预期要求,读者应当能够熟练查询所需使用的软件的文档与手册。
- 知其然,知其所以然:我们会尽量解释为什么要做某件事情,其底层逻辑是怎样的,而不仅仅是怎么做。我们希望读者能够理解背后的原理,而不仅仅是机械地操作。(况且,了解底层的运行规律,也是一件很有趣的事情!)
- 取自实践,鼓励实践:本教程的内容大多取自我们的实际运维经验,而非空谈。并且,本教程也希望读者能够在阅读的同时动手,在自己的环境中尝试。
Expand All @@ -18,6 +18,7 @@ icon: material/heart
- 能够相对熟练地使用 C 和 Python 语言编写自己所需的程序。
- 了解 Linux 101 的内容,并且有能力完成其中的练习。
- 有能力配置可用的 Debian 系统环境(实机/虚拟机/容器等)。
- 能够正确使用 Google 等搜索方式,并相对熟练地阅读英语资料。

除此之外,部分章节可能依赖于其他计算机科学的知识,例如数据库、计算机网络等。如果对前置要求不熟悉,建议先学习相关的知识。作为参考,[cs-self-learning](https://csdiy.wiki/) 提供了不错的自学教程目录。

Expand Down
21 changes: 17 additions & 4 deletions docs/ops/storage/zfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ $
为了确保最佳的性能,`ashift` 参数应当与硬盘的真实扇区大小相匹配,既不宜过大也不宜过小。
默认情况下,在创建 zpool 的时候,ZFS 会自动检测硬盘的扇区大小(`ioctl(BLKPBSZGET)`)并设置合适的 `ashift` 参数。
对于固态硬盘,建议查阅硬盘的规格,然后手动指定 `zpool create -o ashift=...`。
如果你不确定硬盘的物理扇区大小(尤其是对于消费级固态硬盘),使用 4K(`ashift=12`)是一个保守但合理的选择。

在生产环境中,请**不要**将 ZFS 用于任何虚拟硬盘或软件/硬件 RAID 阵列上。
只有当 ZFS 直接管理每块硬盘时,才能获得最佳的性能和 ZFS 提供的数据完整性保证。
如果你的阵列卡不支持直通,可以考虑为每块盘建立一个单盘阵列
如果你的阵列卡不支持直通,可以考虑为每块盘建立一个单盘阵列以最小化阵列卡的影响

在实际应用中,如果你使用 `sda``nvme0n1` 等设备名来创建 pool,ZFS 会自动对其进行分区,然后使用 `sda1``nvme0n1p1` 等分区名来创建 pool,并在每个盘的末尾创建一个 8 MB 的分区(`sda9``nvme0n1p9`)。分区的目的可能出于某些历史原因,目前无从考证,且这个编号为 9 的分区是没有任何用途的。

Expand Down Expand Up @@ -105,12 +106,18 @@ tank 2.81G 112K 2.81G - - 0% 0% 1.00x ONLINE -

Zpool 层面的参数可以通过 `zpool set` 命令进行调整,以下是一些推荐修改的参数:

- `ashift`:详见上面的介绍。注意 `ashift` 参数在创建 pool 后**无法更改**,因此请在创建 pool 时指定。

- `autotrim=on`:如果你使用硬盘是 SSD,启用此选项后 ZFS 会自动为已删除的数据块向硬盘发送 TRIM 指令。例如:

```shell
zpool set autotrim=on tank
```

以下是一些在特定情况下有用的参数:

- `bootfs=pool0/ROOT/debian`:如果你使用 root on ZFS,该参数是常见的 grub 配置及 initramfs 生成脚本所需的参数。

### ZFS 文件系统 {#tuning-zfs}

ZFS(文件系统)层面的参数可以通过 `zfs set` 命令进行调整,语法与 `zpool set` 类似。以下是一些推荐修改的参数:
Expand All @@ -121,13 +128,19 @@ ZFS(文件系统)层面的参数可以通过 `zfs set` 命令进行调整,

该选项的默认值为 `xattr=on`,即扩展属性存储在额外的数据块中。这是为了保持与 FreeBSD / Solaris 等系统中的 ZFS 实现的兼容性。除非你预计需要将 ZFS pool 搬到这些系统上使用,否则我们推荐使用 `xattr=sa``xattr=off`

- `relatime=on`:启用相对时间戳。默认情况下,Linux 会在**每次**访问文件时更新其访问时间戳(atime),对于经常访问但较少修改的文件来说,这会带来额外的磁盘 I/O。启用 `relatime` 后,Linux 会降低对 atime 的更新频率,从而减少磁盘 I/O。

此 ZFS 参数与 Linux 的挂载选项 `relatime` 完全相同。

- `compression=on``compression=zstd`:启用 ZFS 的透明压缩功能。对于大多数数据,压缩后的数据量会显著减小,从而减少磁盘 I/O。

一般建议启用透明压缩功能,除非你的 CPU 性能较差(例如 10 年前的服务器)或者预期的数据量不会因压缩而减小(例如归档存储已经压缩过的数据)。

!!! note "压缩算法"

截至 2024 年,ZFS 默认使用 LZ4 算法进行压缩,这是一种速度较快的单线程算法。如果你的 CPU 不是上古级别的,可以考虑使用 Zstd,这是一种更加现代化的压缩算法,支持多线程和更高的压缩比。
截至 2024 年,ZFS 的默认(`compression=on`)压缩算法为 LZ4,这是一种速度较快的单线程算法。如果你的 CPU 不是上古级别的,可以考虑使用 Zstd,这是一种更加现代化的压缩算法,支持多线程和更高的压缩比。

OpenZFS 在 2.2 版本中为 3 级以上的 Zstd 启用了 early abort(默认等级刚好是 3 级),即 ZFS 会先使用 LZ4 和 Zstd-1 尝试压缩,如果压缩比不理想,则放弃压缩。Early abort 机制可以避免在难以压缩的数据上浪费 CPU,因此一般情况下无需担心压缩会带来性能问题。

### ZFS 内核模块参数 {#tuning-zfs-ko}

Expand Down Expand Up @@ -155,7 +168,7 @@ echo 4294967296 > /sys/module/zfs/parameters/zfs_arc_max
在 Linux 下,受限于 kernel 的设计 (1),ARC 占用的内存会在 htop / free 等程序中显示为 used 而不是 cached,但是其行为和 cached 是一致的,即在系统内存压力升高时会自动释放,以供其他程序使用。
{: .annotate }

1. 在 FreeBSD 中,ZFS ARC 占用的内存会正确地显示为 cached。
1. 在 FreeBSD 和 htop ≥ 3.3.0 中,ZFS ARC 占用的内存会正确地显示为 cached。

!!! tip "强制释放 ARC"

Expand All @@ -176,7 +189,7 @@ ZFS 提供了调试工具 `zdb`,可以用于查看 pool 和文件系统的内

- `zdb` 不关心 pool 或者文件系统是否挂载,它都会直接访问块设备。因此在正在使用的 pool 或者文件系统上使用 `zdb` 可能会得到不一致的结果;
- `zdb` 的输出格式没有文档说明,因为其假设使用者了解 ZFS 的内部结构;
- `zdb` 支持写入内容,但是在不了解 ZFS 内部结构的情况下,建议仅使用 `zdb` 读取 pool 和文件系统的结构内容
- `zdb` 支持写入内容,但是在不了解 ZFS 内部结构的情况下,建议以只读方式使用 `zdb`

以下提供了一个使用 `zdb` 调试出生产环境「未解之谜」的例子:

Expand Down

0 comments on commit 3b9f986

Please sign in to comment.