如何在 zfs 中“重新平衡”数据?(确保数据分布在所有条带镜像中)

如何在 zfs 中“重新平衡”数据?(确保数据分布在所有条带镜像中)

以条带镜像 (Raid 10) 为例,如果将两个磁盘扩展到四个,那么如何在两个镜像之间“重新平衡”(分散)两个磁盘上的数据?

也就是说,如何才能将原本写入一个镜像的文件写入两个镜像,以利用条带磁盘的优势?

答案1

只有新写入(附加)的数据才会在所有当前活动的 vdev 之间分配,ZFS 中没有明确的重新平衡操作。

两种可能的解决方案:

  1. 等到所有旧数据再次写入(由于 CoW,这可能需要很长时间,在最坏的情况下是完全写入磁盘所需时间的两倍)。
  2. 删除所有数据并重新写入(zfs send/recv 有助于将所有数据从池中取出并返回而不会丢失任何内容)。这不必一次性完成,并且可以在同一个池中完成。

更准确地说,我会选择第二种解决方案,并在系统负载较低时(例如晚上)单独传输每个文件系统:

  • zfs snapshot -r对大小合适的文件系统(以及其子文件系统,以递归方式)进行快照( )
  • 使用zfs send | zfs recv适当的选项将快照发送到新创建的临时文件系统(如果空间允许,可以位于同一池中);此文件系统应与旧文件系统位于层次结构中的同一位置
  • 复制完成后(可能需要一些时间,因为磁盘必须读写),zfs destroy旧快照和旧文件系统
  • zfs rename临时系统改为旧名
  • 使用检查和更改挂载点zfs mount,重新排列替换文件系统的先前情况
  • 重复此操作,直到所有文件系统均已移动

答案2

可能的第三种解决方案(正如 SirMaster 在 FreeNAS 论坛中提到的邮政):

  • 将新磁盘添加到 zpool
  • 将许多文件复制到另一个新的 /mnt/pool/temp/ 目录
  • 删除原有文件:rm -rf original/
  • 将目录重命名为:mv temp/ original/

这是因为 ZFS 会按比例将写入内容放到具有最多可用空间的 vdev 中,在本例中是全新的空驱动器。(从 0.7 开始,zfs 将更倾向于更快的驱动器进行写入,但假设您的 2 个新驱动器的性能与原始驱动器相同或更高)

它可能比慢zfs send | zfs recv,但更简单,因为您不必创建/销毁快照。

您可以运行zpool list -v之前和之后来查看每个 vdev 的利用率。

另外,发现了一个 php脚本它逐个文件地执行复制/删除/重命名过程。这链接在回答来自类似(但 zvol)问题大几岁。(没有亲自测试过这个脚本)

答案3

这与 user121391 的答案类似,但我刚刚使用 Jim Salter 的优秀博客文章从几年前开始。本质上,你:

  1. 清理你的池并检查状态。
  2. 使用 从每个镜像中释放一个磁盘zpool detach
  3. 使用释放的磁盘创建一个新池。
  4. 将数据复制到新池。我使用了他的syncoid这个。
  5. 清理新池并验证状态。
  6. zpool destroy在念完你需要念叨的祝福语后,你就会发现自己已经被困在旧游泳池里了。
  7. zpool attach将剩余磁盘添加到新池。
  8. 将新池重命名为原始名称。

相关内容