将相同的数据写入 ZFS 下的文件块会占用快照中的空间吗?

将相同的数据写入 ZFS 下的文件块会占用快照中的空间吗?

我有一个16M的文件。

我拍摄了包含它的 ZFS 文件系统的快照。

如果我用相同的数据覆盖文件,ZFS 是否需要存储文件所有块的两个副本?

答案1

是的,如果从文件集获取快照,ZFS 将为同一个文件分配额外的空间。

首先,让我们创建一个空文件集并准备一个要从中复制的文件。出于简单原因,压缩已关闭,并且池是在单个磁盘上创建的,没有任何雷兹或者镜子

[root@localhost ~]# dd if=/dev/urandom of=/tmp/testfile bs=16M count=1
1+0 records in
1+0 records out
16777216 bytes (17 MB) copied, 0.113345 s, 148 MB/s    


[root@localhost ~]# zpool create tank sdd
[root@localhost ~]# zfs create tank/test

磁盘上使用的空间可以通过 来查看zpool list

[root@localhost]# zpool list tank
NAME     SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank    9.94G   182K  9.94G         -     0%     0%  1.00x  ONLINE  -

现在将文件复制到 ZFS 文件集,创建快照并查看使用的空间。

[root@localhost ~]# /bin/cp /tmp/testfile /tank/test/

[root@localhost ~]# zfs list -t all -r tank/test
NAME        USED  AVAIL  REFER  MOUNTPOINT
tank/test  16.0M  9.61G  16.0M  /tank/test

[root@localhost ~]# zfs snapshot tank/test@1
[root@localhost ~]# zfs list -t all -r tank/test
NAME          USED  AVAIL  REFER  MOUNTPOINT
tank/test    16.0M  9.61G  16.0M  /tank/test
tank/test@1     0B      -  16.0M  -

好的,再次将相同的文件复制到 ZFS 文件集中的相同位置,然后再次查看使用的空间。

[root@localhost ~]# /bin/cp -f /tmp/testfile /tank/test/
[root@localhost ~]# zfs list -t all -r tank/test
NAME          USED  AVAIL  REFER  MOUNTPOINT
tank/test    32.0M  9.60G  16.0M  /tank/test
tank/test@1  16.0M      -  16.0M  -

此外,池中使用的磁盘空间增长到 32MB。

[root@localhost tank]# zpool list tank
NAME     SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank    9.94G  32.2M  9.91G         -     0%     0%  1.00x  ONLINE  -

如您所见,tank/test文件集现在总共占 32MB,其中文件集分为 16MB tank/test,快照中分为 16MB tank/test@1。输出还zpool list显示磁盘上分配了 32MB。
如果你重复复制并拍摄快照USED​​ 总量tank/test将进一步增长。

更新

感谢@Andrew Henle 的询问。必须更新我上面的答案并将继续重复数据删除下面的东西。

让我们用一个文件集再次执行此操作重复数据删除已启用。

[root@localhost]# zfs destroy -r tank/test
[root@localhost]# zfs create tank/test-dedup
[root@localhost]# zfs set dedup=on tank/test-dedup

我将跳过此处的单个步骤,仅添加已用空间概述的输出。

[root@localhost ~]# zfs list -t all -r tank/test-dedup
NAME                  USED  AVAIL  REFER  MOUNTPOINT
tank                 32.3M  9.61G    24K  /tank
tank/test-dedup      32.1M  9.61G  16.0M  /tank/test-dedup
tank/test-dedup@1    16.0M      -  16.0M  -
[root@localhost ~]# zpool list tank
NAME     SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank    9.94G  16.3M  9.92G         -     0%     0%  2.00x  ONLINE  -

重复数据删除启用后,快照仍报告使用额外的大小,但正如你所看到zpool list重复数据删除节省磁盘空间,重复数据删除率为 2。

IIRC 通常不建议使用重复数据删除,因为内存使用量很大并且会影响性​​能。我认为正在改进 ZFS 中的重复数据删除功能。

答案2

我知道这已经很旧了,但是(至少对于 OpenZFS 的某些版本)您可以使用以下方法避免相同块的额外分配空写

ZFS 支持每个数据块的端到端校验和。当使用加密安全校验和(并且启用压缩)时,OpenZFS 会将传入写入的校验和与现有磁盘数据的校验和进行比较,并避免对未更改的数据发出任何写入 I/O。在相同文件定期被几乎相同的数据覆盖的情况下(例如大型随机访问文件的定期完整备份),这可以帮助提高性能和快照空间使用率。

相关内容