Skip to content

zfs文件系统笔记

目录

为什么使用 zfs

zfs 是一个先进的文件系统,它提供了许多传统文件系统不具备的功能,如快照、克隆、数据完整性检查、数据压缩、数据加密等。

主要还是想尝试新的东西

如何学习 zfs

zfs 实现了存储池和文件系统的分离,为了方便理解学习,我把 zfs 分为 2 部分,一部分是存储池,一部分是文件系统 ** 存储池负责管理磁盘,与硬件交互,决定如何分配数据,如何保证数据的完整性,如何保证数据的安全性

文件系统负责管理文件,与用户交互,决定如何组织文件,如何保证文件的完整性,如何保证文件的安全性

简单点说就是存储池负责把任意个磁盘抽象成一个大的存储空间,文件系统在这个大的存储空间上创建不同的文件夹,这些文件夹可以嵌套,可以单独挂载,比一般意义上的“文件夹”概念更加强大,更类似于“磁盘分区”的概念,所以也叫“文件系统”。

并且这两者使用的命令也不同,存储池使用 zpool 命令,文件系统使用 zfs 命令

相关命令可见:https://openzfs.github.io/openzfs-docs/man/master/8/index.html

安装 zfs

shell
sudo apt update
sudo apt install zfsutils-linux -y

存储池 zpool

管理存储池使用 zpool 命令

创建 zfs 存储池

shell
sudo create [-fnd] [-o property=value] ... [-O file-system-property=value] ... [-m mountpoint] [-R root] <pool> <vdev> ...

sudo zpool create -f -o ashift=12 -m <mountpoint> <pool_name> [raidz|raidz2|raidz3|mirror] <volumes>

可以看到 只有存储池名和存储盘是必须的,其他都是可选的,其他参数的意义如下:

  • -f 用于避免 Does not contain an EFI label 错误。
    这个可能是 Linux 上的特定问题,在别的系统上可能不需要。无论怎么说,请参阅手册与文档。
  • -o ashift=12 使用现代硬盘原生支持的 AF (Advanced Format,先进格式化) 中的 4K 块大小以增进性能。如果你的存储池全部使用 SSD 的话,应使用 -o ashift=13 (因为 SSD 一般使用 8K 块)
    OpenZFS docs 上有更多有关这个问题的信息。
  • -m <mountpoint> 指定默认挂载点。
  • <pool_name> 指定存储池名。
  • [raidz|raidz2|raidz3|mirror] <volumes> 指定 VDEV 类型。不使用冗余则省略 VDEV 类型标识。注意这段可重复多次以创建拥有多个 VDEV 的阵列。

在指定存储盘时注意使用盘的持久标识(如 /dev/disks/by-id 内标注的),而不是非持久标识(如 sdXnvmeX)。一旦硬盘排布发生变化(例如增减了硬盘),使用非持久标识的阵列在开机时可能会找不到或使用了错误的存储盘,而导致挂载失败。使用持久标识则可避免这个问题。

例子

例子:创建无冗余的单盘存储池

shell
sudo zpool create -f -o ashift=12 -m /mnt/data data ata-VOLUME-ID

这里,我们在一块机械硬盘( /dev/disk/by-id/ata-VOLUME-ID )上创建了一个存储池,并挂载到了 /mnt/data 上。 例子:创建由镜像 VDEV 组成的存储池

shell
sudo zpool create -f -o ashift=12 -m /mnt/data data mirror ata-VOLUME-1 ata-VOLUME-2

这样就创建了一个拥有一个镜像 VDEV (由 ata-VOLUME-1 和 ata-VOLUME-2 组成)的存储池。

也可以在创建时指定多个 VDEV:

shell
sudo zpool create -f -o ashift=12 -m /mnt/data data \
      mirror ata-VOLUME-1 ata-VOLUME-2 \
      mirror ata-VOLUME-3 ata-VOLUME-4

例子:创建由 RAIDz1 VDEV 组成的存储池

shell
sudo zpool create -f -o ashift=12 -m /mnt/data data \
      raidz ata-VOLUME-1 ata-VOLUME-2 ata-VOLUME-3 [...even more volumes]

检查状态

shell
zpool status data

添加磁盘

shell
zpool add [pool_name] [raidz|raidz2|raidz3|mirror] <volumes>

zpool-add.8

简单盘转为 mirror VDEV

这个操作也可以被用来扩展已有的 mirror VDEV。

shell
sudo zpool attach [pool_name] <exisitng_volume/VDEV_name> <new_volumes>

zpool-attach.8 上有更多有关这个操作的信息。

从存储池中去除设备

目前,OpenZFS 只支持从不包含 RAIDz 的存储池中移除 single 和 mirror 类型的 VDEV。这个操作会把数据迁移至剩下的存储盘上,并相应地降低存储池的大小。

shell
zpool remove [pool_name] [devices]

zpool-remove.8

如果删除的是一个 mirror VDEV,则需要使用 zpool detach 命令

shell
zpool detach data ata-VOLUME-1

删除之后需要清理磁盘上的 ZFS 标签

shell
zpool labelclear /dev/*

删除存储池

shell
zpool destroy [pool_name]

导入和导出存储池

如果要在别的设备/操作系统上使用存储池,首先需要将存储池导出。

shell
zpool export <pool_name>

导入存储池时需注意,ZFS on Linux 默认会使用非持久命名导入数据盘。为了避免磁盘排布变化造成无法开机时载入存储池,导入时应注明从哪个位置搜索磁盘:

shell
zpool import -d /dev/disk/by-id <pool_name>

文件系统 zfs

管理文件系统使用 zfs 命令

创建文件系统

shell
sudo zfs create pool_name/fs_name

这将在 pool_name 下创建一个名为 fs_name 的文件系统,通俗点说就是一个文件夹。

并且可以多层嵌套

shell
sudo zfs create pool_name/fs_name1/fs_name2

对于使用 zfs 创建的文件系统,无法使用rm 命令删除,即使你拥有对他完全的权限

zfs-create.8

挂载和卸载

zfs-unmount.8

查看和修改属性

查看文件系统属性

shell
sudo zfs get all [pool_name[/fs_name]]

zfs-set.8

bash
# 查看压缩算法和压缩率
sudo zfs get compression,compressratio | grep -v "@"

数据集优化

recordsize

recordsize 属性用于指定数据集的块大小。这个值应该根据数据集的使用情况来设置,以提高性能。

shell
sudo zfs set recordsize=128K pool_name/fs_name

# 对于视频文件,可以设置更大的块大小
sudo zfs set recordsize=1M pool_name/fs_name

# 对于代码文件,可以设置更小的块大小
sudo zfs set recordsize=8K pool_name/fs_name
compression

compression 属性用于指定数据集的压缩方式。这个值应该根据数据集的使用情况来设置,以提高性能。

可设置的选项:on | off | lzjb | gzip | gzip-[1-9] | zle | lz4 | zstd | zstd-[1-19] | zstd-fast | zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]

常用的有 lz4(默认压缩) 和 zstd

zstd默认使用的是zstd-3,可以根据需要设置更高的压缩率,但是会消耗更多的 CPU 资源。

shell
# 对于视频,图片,安装包等已经压缩过的文件,可以设置为 lze4 。放心,他会自己判断是否压缩
sudo zfs set compression=lz4 pool_name/fs_name

# 对于冷数据,采用zstd 压缩
sudo zfs set compression=zstd pool_name/fs_name

实践来说,zstd-3对于归档文件,图片,软件包,视频等等压缩率还是挺低的,基本只有 1.1 倍左右

atime

atime 属性用于指定数据集的 atime 是否开启。这个值应该根据数据集的使用情况来设置,以提高性能。

shell
# 关闭 atime
sudo zfs set atime=off pool_name/fs_name

快照

zfs-snapshot.8

bash
# 创建快照
zfs snapshot pool_name/fs_name@snapshot_name

# 销毁快照
zfs destroy pool_name/fs_name@snapshot_name # 注意销毁快照和删除池的命令相同

参考资料

lsof /data2

————————————————
版权声明:本文为 田园幻想乡 的原创文章,遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接: http://truraly.fun/学习笔记/ubuntu/软件的安装以及使用/zfs文件系统笔记.html


发布时间:

最后更新时间:

Copyright © 2022 田园幻想乡 浙ICP备2021038778号-1