我目前有两台服务器,它们都有完全相同的硬件、磁盘等。
一台服务器 (server1) 将成为“主”服务器。它基本上是一个带有 raidz2 的服务器,上面有可供人们连接的 SMB 共享。
另一台服务器 (server2) 的配置与 server1 (raidz2) 相同,但仅用于备份 server1。它的目的是作为异地备份,以防我们因磁盘故障、火灾、水灾等而丢失 server1。
我正在尝试找出备份到 server2 的最佳方法。
起初,我想到的是 rsync 之类的东西。这在 cron 中设置起来很简单,我可以每周运行一次。
或者,我正在考虑使用 zfs send/recv 的一些东西。我的理解是ZFS可以做“快照”,所以我认为如果我可以创建快照/增量备份而不丢失大量空间,那就太好了。我觉得这可能更难以实施/容易出错。
还有其他选择吗?
正如我之前所说,两台服务器在硬件和 raidz2 布局方面配置相同。针对我现在的情况,大家有什么建议吗?提前致谢。
答案1
我会使用增量 ZFS 发送/接收。它应该比rsync
ZFS 知道自上一个快照以来发生了什么更改而无需探索整个文件系统更有效。
假设您要完全备份名为 的文件系统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