有没有办法在 ZFS 中创建牛副本?

有没有办法在 ZFS 中创建牛副本?

我正在尝试制作一些文件/目录的原始副本,但在我所知道的几种方法中,所有方法似乎都不是最佳的。

例如,btrfs 可以通过使用cp --reflink=auto快速生成文件的牛副本。

我尝试过的:

  1. 符号链接:不好。文件已重命名,链接已损坏。
  2. 硬链接:更好,但仍然不好。对一个文件的更改将更改另一个文件,并且我不一定希望更改另一个文件。
  3. 创建数据集的快照,然后克隆快照:这可以工作,但效果不佳。通常,我并不是在寻找整个数据集的副本,也不是为了让这些副本像另一个数据集一样工作。然后是克隆/快照/原始之间的父/子关系,据我所知,即使不是不可能打破,也很难打破。
  4. 使用zfs send/receive并启用 dedup,将数据集复制到新数据集:这避免了使用克隆的父/子关系,但仍然不必要地创建另一个数据集,并且仍然受到必须 100% 读取文件所涉及的缓慢问题的困扰再次引用而不是写入的块。
  5. 复制文件并让 dedup 完成其工作:这可行,但速度很慢,因为文件必须 100% 读取,然后再次引用块而不是写入。

zfs 发送/接收以及物理复制或 rsync 的缓慢性进一步加剧,因为大多数内容都是压缩存储的,并且必须在读取期间解压缩,然后在 dedup 启动以引用重复块之前进行压缩。

在我所有的研究中,我还没有找到任何与 btrfs 中的 --reflink 的简单性类似的东西。

那么,有没有办法在 ZFS 中创建牛副本呢?或者“物理”复制并让重复数据删除完成其工作是唯一真正的选择?

答案1

我认为您上面描述的选项 3 可能是您最好的选择。您想要的最大问题是 ZFS 实际上只在数据集/快照级别处理这种写时复制。

我强烈建议避免使用重复数据删除,除非您已确认它适用于您的具体环境。我个人的经验是,重复数据删除工作得很好,直到有一个用户或虚拟机存储被移入,然后它就会掉下性能悬崖并导致很多问题。仅仅因为它看起来对前十个用户运行良好,当您添加第十一个(或第十二个,或第十三个,或其他)时,您的机器可能会崩溃。如果您想走这条路,请绝对确保您有一个完全模仿您的生产环境的测试环境,并且它在该环境中运行良好。

回到选项 3,您需要设置一个特定的数据集来保存要以此方式管理的每个文件系统树。设置并初始填充后,拍摄快照(每个数据集一个,略有不同)并将其升级为克隆。永远不要再接触原始数据集。

是的,这个解决方案有问题。我并不是说它不会,但考虑到 ZFS 的限制,它仍然可能是最好的。我确实发现有人有效地使用克隆:http://thegreyblog.blogspot.com/2009/05/sparing-disk-space-with-zfs-clones.html

我对 btrfs 不太熟悉,但如果它支持您想要的选项,您是否考虑过设置一个单独的服务器来支持这些数据集,并在该服务器上使用 Linux 和 btrfs?

答案2

方案 5 是最好的方案。

对于选项 3 中的父/子数据集,您可以提升克隆,它将不再是克隆数据集的子项。它仍然不会用完额外的块。 编辑:请注意,这只会颠倒父/子关系,而不是破坏它。

关于压缩/加密的内容以及减慢复制速度的说法,这是完全错误的。您的处理器比块设备快得多(即使使用 SSD)。仅举一些示例数字,假设读取一个块需要 10 秒,但解压缩它只需要 1 秒,解密它只需要 2 秒。块 1 在 10 秒内被读取并发送到 CPU。当磁盘开始读取块 2 时,CPU 开始解压缩和解密。CPU 将在 3 秒内完成其任务,然后在接下来的 7 秒内等待磁盘。同时,无论块是否被压缩,磁盘都花费了完全相同的时间来读取这两个块(20 秒)。

同样,在写入时,只有第一个块被延迟。 CPU 压缩/加密块 1 并将其发送到磁盘。当磁盘写入块 1 时,CPU 将开始压缩/加密后续块。 CPU 读取块的速度比磁盘写入块的速度快得多,因此这不是问题。 (是的,它比这更复杂,但这就是要点。)

很抱歉对您问题中的一个小问题的解释过长,但我想澄清这种误解。

相关内容