使用另一台服务器的 ZFS 备份建议

使用另一台服务器的 ZFS 备份建议

我目前有两台服务器,它们具有完全相同的硬件、磁盘等。

一台服务器 (server1) 将成为“主”服务器。它基本上是一台带有 raidz2 的服务器,上面有供人们连接的 SMB 共享。

另一台服务器(server2)的配置与 server1(raidz2)相同,但仅用于备份 server1。如果我们因磁盘故障、火灾、水灾等原因丢失了 server1,它将作为异地备份。

我正在尝试找出对 server2 进行备份的最佳方法。

一开始,我考虑使用 rsync 之类的东西。这很容易在 cron 中设置,我可以每周运行一次。

另外,我正在考虑使用 zfs send/recv。我的理解是 ZFS 可以做“快照”,所以我认为如果我可以在不损失大量空间的情况下创建快照/增量备份,那就太好了。我觉得这可能更难实现/更容易出错。

正如我之前所说,两台服务器的硬件和 raidz2 布局配置相同。对于我目前的情况,你们有什么建议吗?

答案1

ZFS 非常有弹性。传输文件系统的最基本示例是:

# zfs snapshot tank/test@tuesday
# zfs send tank/test@tuesday | ssh [email protected] "zfs receive pool/test"

注意发送之前的快照(以及发送快照)。

您可以将其打包成一个脚本,在将本地快照发送到远程服务器后删除它——或者如果您有足够的磁盘空间,也可以保留它。将以前的快照保留在备份服务器上。

来源及强烈推荐阅读:https://pthree.org/2012/12/20/zfs-administration-part-xiii-sending-and-receiving-filesystems/

答案2

我会使用增量 ZFS 发送/接收。它应该比 ZFS 更高效,rsync因为 ZFS 知道自上次快照以来发生了什么变化,而无需探索整个文件系统。

假设您想要完整备份文件系统 namen datapool/fs

首先创建一个池,在目标服务器上存储备份,并在源池上存储递归快照:

dest # zpool create datapool ...
source # zfs snapshot -r datapool/fs@snap1

然后您将整个数据作为初始备份发送:

source # zfs send -R datapool/fs@snap1 | ssh dest zfs receive datapool/fs

下周(或任何你喜欢的时间段),你将在源池上创建第二个快照,并将其逐步发送到目标上。那时,ZFS 足够智能,只会发送一周内发生变化的内容(删除、创建和修改的文件)。当文件被修改时,不会将其作为一个整体发送,而只会传输和更新修改后的块。

source # zfs snapshot -r datapool/fs@snap2
source # zfs send -ri snap1 datapool/fs@snap2 | 
            ssh dest zfs receive -F datapool/fs

每次备份时重复此操作并增加快照编号。

当您不再需要时,请删除任一服务器上未使用的旧快照。

如果您有带宽限制,您可以动态压缩/解压缩数据,例如在管道中插入gzip/zip命令或启用 ssh 压缩。

source # zfs send -ri snap1 datapool/fs@snap2 | gzip | 
            ssh dest "gunzip | zfs receive -F datapool/fs"

您还可以利用mbuffer更稳定的带宽使用率,如本文所述

dest # mbuffer -s 128k -m 1G -I 9090 | zfs receive datapool/fs

source # zfs send -i snap2 datapool/fs@snap3 | 
            mbuffer -s 128k -m 1G -O w.x.y.z:9090

注意:该zfs -r标志不适用于非 Solaris ZFS 实现,请参阅 http://lists.freebsd.org/pipermail/freebsd-fs/2012-September/015074.html。在这种情况下,不要-F在目标上使用标志,而是明确回滚数据集。如果在源上创建了新的数据集,请先独立发送它们,然后再执行快照 + 增量发送/接收。

当然,如果您只有一个文件系统需要备份而没有底层数据集层次结构,或者您想要执行独立备份,则增量备份更易于实现,并且无论 ZFS 实现如何,其工作方式都应该相同:

T0:

zfs snapshot datapool/fs@snap1
zfs send datapool/fs@snap1 | ssh dest zfs receive datapool/fs

T1:

zfs snapshot datapool/fs@snap2
zfs send -i snap1 datapool/fs@snap2 | 
            ssh dest zfs receive -F datapool/fs

答案3

我在使用 zfs send/receive 向远程发送 1 TB 数据时遇到了问题。我决定打破单个 1TB 文件系统,使其包含多个子文件系统。现在,在发生网络故障后,最坏情况下只需要重新发送一个子文件系统。我使用脚本来处理递归发送并保持远程同步:https://github.com/dareni/shellscripts/blob/master/zfsDup.sh

我希望这个脚本能够对其他人有用。

示例输出:

# zfsDup.sh shelltests
Test: array_add()
Test: array_clear()
Test: array_iterator()
Test: nameValidation()
Test: isValidSnapshot()
Test: getSnapshotFilesystems()
Test: getSnapshotData()
Test: getRemoteDestination()
Test: printElapsed()
Test: convertToBytes()
Shell tests completed, check the output for errors.

# zfsDup.sh zfstests
Start zfs tests.
Test: new parent file system.
Test: new child file system.
Test: simulate a failed send of the child filesystem.
Test: duplicate and check the child@2 snapshot is resent.
Test: snapshot existing files with updated child data.
Test: simulate a fail send os child@3
Test: snapshot test1.
Test: snapshot test2.
Test: snapshot test3.
Snapshot tests completed ok.
Test: remote host free space.
Test: new remote FS with no quota.
Test: incremental remote FS update with no quota.
Cleaning up zroot/tmp/zfsDupTest/dest zroot/tmp/zfsDupTest/source
Test execution time: 89secs
ZFS tests completed, check the output for errors.


# zfs list -t all -r ztest
NAME  USED  AVAIL  REFER  MOUNTPOINT
ztest  344K  448M  19K  /ztest
ztest@1  9K  -  19K  -
ztest@6  9K  -  19K  -
ztest/backup  112K  448M  19K  /ztest/backup
ztest/backup@1  9K  -  19K  -
ztest/backup@2  0  -  19K  -
ztest/backup@3  0  -  19K  -
ztest/backup@4  9K  -  19K  -
ztest/backup@5  0  -  19K  -
ztest/backup@6  0  -  19K  -
ztest/backup/data  57.5K  448M  20.5K  /ztest/backup/data
ztest/backup/data@1  0  -  19.5K  -
ztest/backup/data@2  0  -  19.5K  -
ztest/backup/data@3  9K  -  19.5K  -
ztest/backup/data@4  9K  -  19.5K  -
ztest/backup/data@5  0  -  20.5K  -
ztest/backup/data@6  0  -  20.5K  -

# zfs list -t all -r zroot/tmp
NAME  USED  AVAIL  REFER  MOUNTPOINT
zroot/tmp  38K  443M  19K  /tmp
zroot/tmp/zfsDupTest  19K  443M  19K  /tmp/zfsDupTest

# zfsDup.sh ztest zroot/tmp root@localhost
================================================================================
Starting duplication 20151001 16:10:56 ...
[email protected]
ztest/[email protected]
ztest/backup/[email protected]
Duplication complete 20151001 16:11:04.
================================================================================

# zfsDup.sh ztest zroot/tmp root@localhost
================================================================================
Starting duplication 20151001 16:11:25 ...
[email protected] to date
ztest/[email protected] to date
ztest/backup/[email protected] to date
Duplication complete 20151001 16:11:29.
================================================================================

# zfs snapshot -r ztest@7
# zfsDup.sh ztest zroot/tmp root@localhost
================================================================================
Starting duplication 20151001 16:12:25 ...
[email protected]
ztest/[email protected]
ztest/backup/[email protected]
Duplication complete 20151001 16:12:33.
================================================================================

# zfs list -t all -r zroot/tmp
NAME  USED  AVAIL  REFER  MOUNTPOINT
zroot/tmp  124K  442M  19K  /tmp
zroot/tmp/zfsDupTest  19K  442M  19K  /tmp/zfsDupTest
zroot/tmp/ztest  86K  442M  19K  /tmp/ztest
zroot/tmp/ztest@6  9K  -  19K  -
zroot/tmp/ztest@7  0  -  19K  -
zroot/tmp/ztest/backup  58K  442M  19K  /tmp/ztest/backup
zroot/tmp/ztest/backup@6  9K  -  19K  -
zroot/tmp/ztest/backup@7  0  -  19K  -
zroot/tmp/ztest/backup/data  30K  442M  20K  /tmp/ztest/backup/data
zroot/tmp/ztest/backup/data@6  10K  -  20K  -
zroot/tmp/ztest/backup/data@7  0  -  20K  -

答案4

你也可以将发送/接收管道传输到例如bzip2并进行 rsync作为这篇博文注意,从属设备必须设置“只读”。

相关内容