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

Gre*_*reg 10 linux zfs hard-drive disk-space-utilization zfsonlinux

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

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

use*_*391 9

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

两种可能的解决方案:

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

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

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

  • 如果对同一个池执行此操作,是否会影响碎片? (2认同)

小智 7

可能的第三种解决方案(正如 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)问题的答案有关。(没有亲自测试这个脚本)

  • 谢谢,在使用新的 raidz1 vdev 扩展池后,我使用此技术重新平衡了我的家庭实验室。使出了一招。 (3认同)