在Linux上的ZFS

ZFS是由Sun Microsystems设计的一个结合了文件系统和逻辑卷管理器的系统。从{pve} 3.4开始,ZFS文件系统的原生Linux内核移植版被引入作为可选的文件系统,也可以作为根文件系统的一个额外选择。没有必要手动编译ZFS模块 - 所有的包都已包含在内。

通过使用ZFS,即使在低预算硬件上也能够实现最大化的企业功能,通过利用SSD缓存或甚至仅使用SSD,还可以获得高性能的系统。ZFS可以用适度的CPU和内存负载以及简单的管理,来替代成本高昂的硬件RAID卡。

ZFS的一般优势
  • 通过{pve} GUI和CLI轻松配置和管理。

  • 可靠

  • 防护数据损坏

  • 文件系统级别的数据压缩

  • 快照

  • 写时复制克隆

  • 不同的RAID级别:RAID0, RAID1, RAID10, RAIDZ-1, RAIDZ-2, RAIDZ-3, dRAID, dRAID2, dRAID3

  • 可以使用SSD作为缓存

  • 自愈

  • 持续完整性检查

  • 设计用于高存储容量

  • 异步复制通过网络

  • 开源

  • 加密

  • 省略号`…​`在中英文中均可用作表示省略或暂停,所以这里不需要翻译。

硬件

ZFS严重依赖于内存,因此你至少需要8GB的内存才能开始。在实践中,根据你的硬件/预算尽可能多地使用内存。为了防止数据损坏,我们推荐使用高质量的ECC内存。

如果您使用专用的缓存和/或日志磁盘,您应该使用企业级SSD。这可以显著提高整体性能。

Important
不要在具有自己的缓存管理的硬件RAID控制器之上使用ZFS。ZFS需要直接与磁盘通信。使用HBA适配器或者像是刷成“IT”模式的LSI控制器会更合适。

如果您正在尝试在虚拟机(嵌套虚拟化)内安装 {pve},不要使用 virtio 作为该虚拟机的磁盘,因为它们不被ZFS支持。请改用IDE或SCSI(也适用于`virtio` SCSI控制器类型)。

安装为根文件系统

当你使用 {pve} 安装器进行安装时,可以为根文件系统选择ZFS。你需要在安装时选择RAID类型:

RAID0

也被称为“条带化”。这种卷的容量是所有磁盘容量的总和。但是RAID0没有增加任何冗余,因此单个驱动器的故障将使卷不可用。

RAID1

也被称为“镜像”。数据被一致地写入所有磁盘。这种模式至少需要2个相同大小的磁盘。最终的容量是单个磁盘的容量。

RAID10

RAID0和RAID1的组合。至少需要4块磁盘。

RAIDZ-1

RAID-5变种,单一奇偶校验。至少需要3个磁盘。

RAIDZ-2

RAID-5的一个变体,双重奇偶校验。至少需要4个磁盘。

RAIDZ-3

RAID-5的一种变体,三重奇偶校验。至少需要5块磁盘。

安装程序会自动对磁盘进行分区,创建一个名为 rpool 的ZFS池,并在ZFS子卷 rpool/ROOT/pve-1 上安装根文件系统。

创建了一个名为`rpool/data`的子卷,用于存储虚拟机映像。为了使用{pve}工具,安装程序在`/etc/pve/storage.cfg`中创建了以下配置项:

zfspool: local-zfs
	pool rpool/data
	sparse
	content images,rootdir

安装后,您可以使用 zpool 命令查看您的ZFS池状态:

# zpool status
  pool: rpool
 state: ONLINE
  scan: none requested
config:

NAME        STATE     READ WRITE CKSUM
	rpool       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    sda2    ONLINE       0     0     0
	    sdb2    ONLINE       0     0     0
	  mirror-1  ONLINE       0     0     0
	    sdc     ONLINE       0     0     0
	    sdd     ONLINE       0     0     0

错误:没有已知的数据错误

zfs`命令用于配置和管理您的ZFS文件系统。以下命令在安装后列出所有文件系统:

# zfs list
NAME               USED  AVAIL  REFER  MOUNTPOINT
rpool             4.94G  7.68T    96K  /rpool
rpool/ROOT         702M  7.68T    96K  /rpool/ROOT
rpool/ROOT/pve-1   702M  7.68T   702M  /
rpool/data          96K  7.68T    96K  /rpool/data
rpool/swap        4.25G  7.69T    64K  -

ZFS RAID级别考虑事项

在选择ZFS池的布局时需要考虑一些因素。ZFS池的基本构建单元是虚拟设备,或称为`vdev`。池中的所有vdev都被平等使用,并且数据在它们之间分条存储(RAID0)。有关vdevs的更多详细信息,请检查`zpoolconcepts(7)`手册页。

性能

每种`vdev`类型的性能表现各不相同。两个感兴趣的参数是IOPS(每秒输入/输出操作数)和可以写入或读取数据的带宽。

一个"镜像" vdev(RAID1)在写入数据时的表现大致与单个磁盘相当。而在读取数据时,性能将随镜像中磁盘数量的增加而线性扩展。

一个常见的情况是拥有4个磁盘。当将其设置为2个镜像vdevs(RAID10)时,池在IOPS和带宽方面的写入特性将与两个单独磁盘相同。对于读取操作,它将类似于4个单独磁盘。

任何冗余级别的“RAIDZ”在IOPS表现上大致相当于单个硬盘,但具有大量的带宽。具体的带宽取决于RAIDZ虚拟设备的大小和冗余级别。

一个’dRAID’池应该与等效的’RAIDZ’池的性能相匹配。

对于运行中的虚拟机,IOPS在大多数情况下是更重要的指标。

尺寸、空间使用和冗余

由“镜像”vdevs组成的池将拥有最佳的性能特征,但可用空间将是可用磁盘的50%。如果一个镜像vdev由超过2个磁盘组成,例如在一个三向镜像中,可用空间会更少。至少每个镜像中需要一个健康的磁盘,以保持池的功能。

'''一个N个磁盘的’RAIDZ’类型vdev的可用空间大致为N-P,其中P表示RAIDZ级别。RAIDZ级别表明有多少块任意磁盘可以在不丢失数据的情况下失效。一个特殊情况是一个有4个磁盘的池使用RAIDZ2。在这种情况下,通常更好的选择是使用2个镜像vdev,因为它们会有更好的性能,同时可用空间将会是相同的。'''

在使用任何RAIDZ级别时,另一个重要因素是ZVOL数据集(用于VM磁盘)的行为方式。对于池中的每一个数据块,它需要至少等于池的`ashift`值定义的最小块大小的奇偶校验数据。如果ashift值为12,那么池的块大小为4k。ZVOL的默认块大小为8k。因此,在RAIDZ2中,每写入一个8k的块,将导致写入两个额外的4k奇偶校验块,8k + 4k + 4k = 16k。当然,这是一种简化的方法,实际情况会因元数据、压缩等因素而略有不同,这些在这个例子中没有被考虑。

当检查以下ZVOL属性时,可以观察到这种行为。

  • volsize

  • "`refreservation`(如果存储池没有使用薄配置)"

  • "`used` (if the pool is thin provisioned and without snapshots present)" 如果池是薄置备的并且没有快照存在

# zfs get volsize,refreservation,used <pool>/vm-<vmid>-disk-X

"`volsize` 是磁盘展示给虚拟机的大小,而 refreservation 显示了池中保留的空间,其中包括预期的奇偶校验数据所需的空间。如果池是薄置备的,那么 refreservation 将被设置为0。另一种观察行为的方法是比较虚拟机内部的已使用磁盘空间和 used 属性。请注意,快照会造成该值的偏差。"

有几种方法可以对抗空间使用的增加:

  • 增加 volblocksize 以提高数据到奇偶校验的比例。

  • 使用’mirror' vdevs 而不是 'RAIDZ'

  • 使用 ashift=9(块大小为512字节)

volblocksize` 属性只能在创建 ZVOL 时设置。默认值可以在存储配置中更改。执行此操作时,需要相应调整客户端,并且根据使用情况,写放大问题可能只是从 ZFS 层移动到了客户端。

在创建存储池时使用`ashift=9`可能会根据底层的硬盘情况导致性能不佳,并且之后无法更改。

镜像vdevs(RAID1,RAID10)对于虚拟机工作负载有着良好的表现。除非你的环境有特定的需求和特性,使得RAIDZ的性能特点是可接受的,否则请使用镜像vdevs。

ZFS dRAID

在ZFS dRAID(分散式RAID)中,热备用驱动器参与RAID阵列。它们的备用容量被保留并用于重建,当某个驱动器出现故障时使用。这根据配置不同,与RAIDZ相比,在驱动器出现故障时可以提供更快的重建速度。更多信息可以在官方OpenZFS文档中找到。脚注:[OpenZFS dRAID https://openzfs.github.io/openzfs-docs/Basic%20Concepts/dRAID%20Howto.html]。

Note
dRAID 旨在用于超过10-15个硬盘的dRAID配置中。对于少量硬盘的大多数使用情况,RAIDZ设置应该更合适。
Note
图形用户界面(GUI)需要比最小值多一个磁盘(例如,dRAID1需要3个)。它还期望添加一个备用磁盘。

dRAID1`或`dRAID`:至少需要2块磁盘,其中一块可以在数据丢失前出现故障。 * dRAID2`:至少需要3个磁盘,数据丢失前可以有两个磁盘故障。 * dRAID3`:至少需要4块磁盘,数据丢失之前可以有三块磁盘失败

更多信息可以在手册页面找到:

# man zpoolconcepts

备件和数据

spares` 的数量告诉系统在磁盘发生故障时应该准备好多少块磁盘。默认值是 0 spares。如果没有备用磁盘,重建过程不会获得任何速度上的好处。

data` 定义了冗余组中的设备数量。默认值是 8. 除了当`disks - parity - spares`的结果小于8时,会使用较小的数字。一般来说,较少的`data`设备数量会导致更高的IOPS、更好的压缩比以及更快的重新银化速度,但是定义更少的数据设备会减少池的可用存储容量。

引导加载程序

{pve} 使用 proxmox-boot-tool 来管理启动加载程序配置。有关详情,请参阅 {pve} 主机引导加载程序 章节。

ZFS 管理

这一部分为您提供了一些常见任务的使用示例。ZFS本身非常强大,提供了许多选项。管理ZFS的主要命令是`zfs`和`zpool`。这两个命令都配有详细的手册页,可以通过以下方式阅读:

# man zpool
# man zfs
-----

[[sysadmin_zfs_create_new_zpool]]
创建一个新的zpool
^^^^^^^^^^^

要创建一个新的存储池,至少需要一块磁盘。`ashift`应该具有与底层磁盘相同的扇区大小(`ashift`的2的幂)或更大。

zpool create -f -o ashift=12 <pool> <device>

[TIP]
====
池名称必须遵守以下规则:

* 以一个字母(a-z或A-Z)开头
* 仅包含字母数字字符、`-`、`_`、`.`、`:` 或空格(` `)字符。
* 不能以`mirror`、`raidz`、`draid`或`spare`为开头
* 不得为 `log
====

要激活压缩(参见章节<<zfs_compression,ZFS中的压缩>>):

zfs set compression=lz4 <pool>

[[sysadmin_zfs_create_new_zpool_raid0]]
创建一个新的RAID-0池
^^^^^^^^^^^^^

最少1个磁盘

zpool create -f -o ashift=12 <pool> <device1> <device2>

[[sysadmin_zfs_create_new_zpool_raid1]]
创建一个带有RAID-1的新存储池
^^^^^^^^^^^^^^^^^

至少2个磁盘

zpool create -f -o ashift=12 <pool> mirror <device1> <device2>

[[sysadmin_zfs_create_new_zpool_raid10]]
创建一个使用RAID-10的新池
^^^^^^^^^^^^^^^^

最少4个磁盘

zpool create -f -o ashift=12 <pool> mirror <device1> <device2> mirror <device3> <device4>

[[sysadmin_zfs_create_new_zpool_raidz1]]
创建一个带有RAIDZ-1的新池
^^^^^^^^^^^^^^^^

最少3个磁盘

zpool create -f -o ashift=12 <pool> raidz1 <device1> <device2> <device3>

创建一个使用RAIDZ-2的新存储池
^^^^^^^^^^^^^^^^^^

最少4个磁盘

zpool create -f -o ashift=12 <pool> raidz2 <device1> <device2> <device3> <device4>

请阅读xref:sysadmin_zfs_raid_considerations[ZFS RAID 级别考虑]部分,以便在设置池时,特别是想要使用 RAID-Z 模式时,获得 IOPS 和带宽预期的大致估计。

[[sysadmin_zfs_create_new_zpool_with_cache]]
创建一个带有缓存(L2ARC)的新池
^^^^^^^^^^^^^^^^^^

可以使用专用设备或分区作为二级缓存以提高性能。这样的缓存设备尤其有助于大部分数据相对静态的随机读取工作负载。由于它充当实际存储和内存中的ARC之间的额外缓存层,因此如果由于内存限制需要减少ARC的大小,它也可以提供帮助。

.创建一个带有磁盘缓存的ZFS池

zpool create -f -o ashift=12 <pool> <device> cache <cache-device>

这里只使用了一个`<device>`和一个`<cache-device>`,但是可以使用更多设备,就像在xref:sysadmin_zfs_create_new_zpool_raid0[使用RAID创建新池]中所展示的那样。

请注意,对于缓存设备不存在镜像或RAID模式,它们都是简单地累加起来的。

如果任何缓存设备在读取时产生错误,ZFS将透明地将该请求转向底层存储层。


[[sysadmin_zfs_create_new_zpool_with_log]]
创建一个带有日志(ZIL)的新池子
^^^^^^^^^^^^^^^^^

可以使用专用的驱动器或分区作为ZFS意图日志(ZIL),它主要用于提供安全的同步事务,因此经常用在性能关键路径上,比如数据库,或者其他更频繁发出`fsync`操作的程序。

池作为默认的ZIL位置,将ZIL IO负载转移到一个单独的设备上,可以在缓解主池的同时,帮助减少事务延迟,提高整体性能。

将磁盘用作日志设备,无论是直接使用还是通过分区,建议:

- 使用具有断电保护的快速SSD,因为这些设备的提交延迟要小得多。

- 为分区(或整个设备)至少分配几GB的空间,但使用超过您已安装内存一半以上的空间并不会为您带来任何真正的好处。

.创建具有独立日志设备的ZFS池

zpool create -f -o ashift=12 <pool> <device> log <log-device>

在上面的例子中使用了单个`<device>`和单个`<log-device>`,但是您也可以将其与其他RAID变体结合使用,如xref:sysadmin_zfs_create_new_zpool_raid0[创建一个新的具有RAID的池]部分所述。

你也可以将日志设备镜像到多个设备上,这主要是为了确保如果单个日志设备出现故障,性能不会立即下降。

如果所有的日志设备都失败了,ZFS主池本身将再次被使用,直到日志设备被替换。

[[sysadmin_zfs_add_cache_and_log_dev]]
将缓存和日志添加到现有资源池中
^^^^^^^^^^^^^^^

如果你有一个没有缓存和日志的池,你仍然可以在任何时候添加它们中的一个或两个。

例如,假设你有一块带有断电保护功能的优质企业级SSD,你想用它来提升你的池(pool)的整体性能。

日志设备的最大大小应该约为已安装物理内存的一半,这意味着ZIL大多数情况下只会占用SSD的一小部分,剩余空间可以用作缓存。

首先你需要使用`parted`或`gdisk`在SSD上创建两个GPT分区。

那么你就可以将它们添加到资源池中:

.将一个单独的日志设备和二级缓存同时添加到现有的资源池中。

zpool add -f <pool> log <device-part1> cache <device-part2>

只需将 `<pool>`、`<device-part1>` 和 `<device-part2>` 分别替换为池名称以及指向分区的两个 `/dev/disk/by-id/` 路径。

你也可以分别添加ZIL和缓存。

.向现有的ZFS池添加一个日志设备

zpool add <pool> log <log-device>

[[sysadmin_zfs_change_failed_dev]]
更换失败的设备
^^^^^^^

zpool replace -f <pool> <old-device> <new-device>

.更换失败的可启动设备

根据{pve}的安装方式,它要么是使用`systemd-boot`,要么通过`proxmox-boot-tool`使用GRUB footnote:[系统安装了{pve} 6.4或更高版本,EFI系统安装了{pve} 5.4或更高版本],或者使用普通的GRUB作为引导程序(见xref:sysboot[主机引导程序])。您可以通过运行以下命令来检查:

proxmox-boot-tool status

复制分区表、重新发行GUID以及替换ZFS分区的首要步骤是相同的。为了使系统能够从新磁盘启动,需要执行不同的步骤,这些步骤取决于所使用的引导加载程序。

sgdisk <healthy bootable device> -R <new device>

sgdisk -G <new device>

zpool replace -f <pool> <old zfs partition> <new zfs partition>

NOTE: 使用 `zpool status -v` 命令来监控新磁盘的重银化(resilvering)进程的进展情况。

.使用 `proxmox-boot-tool`:

proxmox-boot-tool format <new disk’s ESP>

proxmox-boot-tool init <new disk’s ESP> [grub]

NOTE: "`ESP` 代表 EFI 系统分区,这是由 {pve} 安装程序自版本 5.4 起在可启动磁盘上设置为分区#2。有关详细信息,请参阅 xref:sysboot_proxmox_boot_setup[设置新分区以用作同步的 ESP]。"

NOTE: 如果`proxmox-boot-tool status`显示您当前的磁盘正在使用GRUB,特别是当启用了Secure Boot时,请确保以'grub'模式传递给`proxmox-boot-tool init`!

.使用普通的GRUB:

grub-install <new disk>

NOTE: 普通的GRUB只在安装了{pve} 6.3或更早版本的系统上使用,这些系统尚未手动迁移到使用`proxmox-boot-tool`。


配置电子邮件通知
~~~~~~~~

ZFS附带一个事件守护进程`ZED`,它监控ZFS内核模块生成的事件。守护进程还可以在发生ZFS事件(如池错误)时发送电子邮件。较新的ZFS包将守护进程分包在一个独立的`zfs-zed`包中,通常情况下这个包在{pve}中应该已经默认安装。

你可以通过你最喜欢的编辑器在文件`/etc/zfs/zed.d/zed.rc`中配置守护进程。电子邮件通知所需的设置是`ZED_EMAIL_ADDR`,默认设置为`root`。

--------
ZED_EMAIL_ADDR="root"
--------

请注意,{pve} 将邮件转发给 `root` 用户配置的电子邮件地址。


[[sysadmin_zfs_limit_memory_usage]]
限制ZFS内存使用
~~~~~~~~~

默认情况下,ZFS会使用主机内存的'50%'来作为**自适应替换缓存**(Adaptive Replacement Cache,简称ARC)。对于从{pve} 8.1开始的新安装,ARC的使用限制将被设置为安装的物理内存的'10%',并限制在最大+16 GiB+。该值将被写入到`/etc/modprobe.d/zfs.conf`中。

为ARC分配足够的内存对于IO性能至关重要,因此请谨慎减少它。作为一个一般的经验法则,至少应该分配+2 GiB基础内存+每TiB存储空间增加1 GiB。例如,如果你有一个+8 TiB+的可用存储空间的池子,那么你应该为ARC使用+10 GiB+的内存。

ZFS 也强制执行最小值 +64 MiB+。

您可以通过直接写入+zfs_arc_max+模块参数来更改当前启动的ARC使用限制(重启会再次重置此更改):

echo "$[10 * 1024*1024*1024]" >/sys/module/zfs/parameters/zfs_arc_max

要**永久更改**ARC限制,请在`/etc/modprobe.d/zfs.conf`文件中添加(或修改已存在的)以下行:

--------
options zfs zfs_arc_max=8589934592
--------

这个示例设置将使用限制为8 GiB('8 * 2^30^')。

IMPORTANT: 如果您想要设置的+zfs_arc_max+值小于等于+zfs_arc_min+(其默认值为系统内存的1/32),则除非您同时将+zfs_arc_min+设为最多+zfs_arc_max - 1+,否则+zfs_arc_max+将会被忽略。

echo "$[8 * 1024*1024*1024 - 1]" >/sys/module/zfs/parameters/zfs_arc_min echo "$[8 * 1024*1024*1024]" >/sys/module/zfs/parameters/zfs_arc_max

这个示例设置(临时)将内存使用限制在8 GiB('8 * 2^30'), 适用于总内存超过256 GiB的系统,在这些系统中,仅设置+zfs_arc_max+是不起作用的。

[IMPORTANT]
====
如果您的根文件系统是ZFS,每次这个值发生变化时,您都必须更新您的initramfs:

update-initramfs -u -k all

你*必须重启*电脑来激活这些更改。
====


[[zfs_swap]]
在ZFS上交换
~~~~~~~

在zvol上创建的交换空间可能会引起一些问题,比如阻塞服务器或产生高IO负载,这种情况常在启动对外部存储的备份时看到。

我们强烈建议使用足够的内存,这样通常不会遇到内存不足的情况。如果你需要或希望添加交换空间,建议在物理磁盘上创建一个分区并将其用作交换设备。你可以在安装程序的高级选项中预留一些空间用于此目的。此外,你可以降低“交换倾向”值。对于服务器来说,10是一个好的值:

sysctl -w vm.swappiness=10

要使交换性(swappiness)设置持久化,用你选择的编辑器打开`/etc/sysctl.conf`文件,并添加以下行:

--------
vm.swappiness = 10
--------

.Linux内核 `swappiness` 参数值
[width="100%", cols="<m,2d", options="header"]
|===========================================================
| 值                  | 策略
| vm.swappiness = 0   | 内核只会在避免“内存不足”条件下才进行交换
| vm.swappiness = 1   | 不完全禁用交换的最小数量。
| vm.swappiness = 10  | 当系统存在足够内存时,有时推荐此值以提高性能。
| vm.swappiness = 60  | 默认值。
| vm.swappiness = 100 | 内核将积极进行交换。
|===========================================================

[[zfs_encryption]]
加密的ZFS数据集
~~~~~~~~~

WARNING: '''{pve}中的原生ZFS加密目前还处于实验阶段。已知的限制和问题包括使用加密数据集进行复制时的问题footnote:[https://bugzilla.proxmox.com/show_bug.cgi?id=2350],以及在使用快照或ZVOLs时出现的校验和错误。footnote:[https://github.com/openzfs/zfs/issues/11688]'''

ZFS在Linux版本0.8.0引入了对数据集本机加密的支持。在从先前的ZFS on Linux版本升级之后,可以按照池启用加密功能:

zpool get feature@encryption tank

NAME PROPERTY VALUE SOURCE tank feature@encryption disabled local

zpool set feature@encryption=enabled

zpool get feature@encryption tank

NAME PROPERTY VALUE SOURCE tank feature@encryption enabled local

WARNING: 目前GRUB不支持从含有加密数据集的池中引导启动,且对于启动时自动解锁加密数据集的支持也有限。不支持加密功能的旧版本ZFS将无法解密存储的数据。

NOTE: 建议在启动后手动解锁存储数据集,或者编写一个自定义单元,在启动时将解锁所需的密钥材料传递给 `zfs load-key`。

WARNING: 在启用生产数据加密之前,建立并测试备份程序。如果相关的密钥材料/密码/密钥文件丢失,将无法再访问加密数据。

在创建数据集/zvols时需要设置加密,并且默认情况下这个设置会继承给子数据集。例如,要创建一个加密的数据集 `tank/encrypted_data` 并在 {pve} 中配置它作为存储,请运行以下命令:

zfs create -o encryption=on -o keyformat=passphrase tank/encrypted_data

Enter passphrase: Re-enter passphrase:

pvesm add zfspool encrypted_zfs -pool tank/encrypted_data

在此存储上创建的所有访客卷/磁盘将使用父数据集的共享密钥材料进行加密。

要实际使用存储空间,需要加载相关的密钥材料并且挂载数据集。这可以通过以下一步完成:

zfs mount -l tank/encrypted_data

Enter passphrase for 'tank/encrypted_data':

也可以通过设置`keylocation`和`keyformat`属性来使用(随机的)密钥文件代替密码提示,这可以在创建时或通过`zfs change-key`在现有数据集上进行。

dd if=/dev/urandom of=/path/to/keyfile bs=32 count=1

zfs change-key -o keyformat=raw -o keylocation=file:///path/to/keyfile tank/encrypted_data

WARNING: 在使用密钥文件时,需要特别注意保护密钥文件不受未授权访问或意外丢失。如果没有密钥文件,将无法访问明文数据!

在加密数据集下创建的客户卷将会相应地设置其`encryptionroot`属性。密钥材料只需要为每个encryptionroot加载一次,就可以对其下所有加密数据集可用。

请参阅`encryptionroot`、`encryption`、`keylocation`、`keyformat`和`keystatus`属性,`zfs load-key`、`zfs unload-key`和`zfs change-key`命令,以及`man zfs`中的`Encryption`部分,以获取更多详细信息和高级用法。


[[zfs_compression]]
ZFS中的压缩
~~~~~~~

当在数据集上启用压缩时,ZFS会在写入之前尝试压缩所有*新*块,并在读取时解压它们。已经存在的数据不会被追溯压缩。

您可以通过以下方式启用压缩:

zfs set compression=<algorithm> <dataset>

我们推荐使用`lz4`算法,因为它几乎不会增加CPU的负担。其他像`lzjb`和`gzip-N`的算法也是可用的,其中`N`是从`1`(最快)到`9`(最佳压缩比)的整数。根据选择的算法以及数据的可压缩性,启用压缩甚至可能提升I/O性能。

您可以随时使用以下方法禁用压缩:

zfs set compression=off <dataset>

再次强调,只有新的区块会受到这次变化的影响。


[[sysadmin_zfs_special_device]]
ZFS 专用设备
~~~~~~~~

自0.8.0版本起,ZFS支持`special`设备。在存储池中,`special`设备用于存储元数据、去重表格,以及可选的小文件块。

一个`特殊`设备可以提高由旋转速度慢的硬盘组成的存储池的速度,尤其是在有大量元数据变化的情况下。例如,涉及创建、更新或删除大量文件的工作负载将从`特殊`设备的存在中受益。ZFS数据集也可以配置为将所有小文件存储在`特殊`设备上,这进一步提高了性能。使用快速的SSD作为`特殊`设备。

IMPORTANT: special`设备的冗余度应该与池的冗余度相匹配,因为`special`设备是整个池的故障点。

WARNING: 向池中添加一个`特别的`设备是无法撤销的!

.创建一个带有`special`设备和RAID-1的池:

zpool create -f -o ashift=12 <pool> mirror <device1> <device2> special mirror <device3> <device4>

.将一个`special`设备添加到已存在的RAID-1池中:

zpool add <pool> special mirror <device1> <device2>

ZFS数据集暴露了`special_small_blocks=<size>`属性。`size`可以是`0`,以禁用在`special`设备上存储小文件块,或者是在`512B`到`1M`范围内的二的幂次方。设置该属性后,小于`size`的新文件块将被分配到`special`设备上。

IMPORTANT: 如果`special_small_blocks`的值大于或等于数据集的`recordsize`(默认`128K`),*所有*数据将被写入`special`设备,所以要小心!

在池(pool)上设置`special_small_blocks`属性将改变该属性对所有子ZFS数据集的默认值(例如,池中的所有容器都将选择小文件块)。

.为所有小于4K块大小的文件选择加入到全局池中:

zfs set special_small_blocks=4K <pool>

.为单个数据集选择启用小文件块:

zfs set special_small_blocks=4K <pool>/<filesystem>

.为单个数据集选择退出小文件块:

zfs set special_small_blocks=0 <pool>/<filesystem>

[[sysadmin_zfs_features]]
ZFS池功能
~~~~~~

在ZFS中,对磁盘格式的更改只在主要版本更迭时进行,并通过*特性*来指定。所有特性以及通用机制都在`zpool-features(5)`手册页中有详细文档说明。

由于启用新特性可能会导致池不可被旧版本的ZFS导入,因此需要管理员主动进行,通过在池上运行 `zpool upgrade` 命令(参见 `zpool-upgrade(8)` 手册页)。

除非你需要使用其中的新功能,否则启用它们没有好处。

实际上,启用新功能也有一些缺点:

* 一个使用ZFS作为根文件系统的系统,如果仍通过GRUB引导启动,并且在rpool上激活了新功能,由于GRUB中ZFS的实现不兼容,这将导致系统无法启动。
* 当系统使用一个较旧的内核启动时,它将无法导入任何升级过的存储池,因为该旧内核仍然附带旧版的ZFS模块。
* 使用较旧的{pve} ISO引导以修复一个无法启动的系统同样不会起作用。

IMPORTANT: 如果您的系统仍然使用GRUB引导,请*不要*升级您的rpool,因为这会导致您的系统无法启动。这包括在{pve} 5.4之前安装的系统,以及使用传统BIOS启动的系统(请参阅xref:sysboot_determine_bootloader_used[如何确定使用的引导加载程序])。

.为ZFS池启用新特性:

zpool upgrade <pool>