我目前有两台服务器,它们具有完全相同的硬件、磁盘等。
一台服务器 (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。作为这篇博文注意,从属设备必须设置“只读”。