我正在通过点对点 T1 线路发送增量 ZFS 快照,并且在下一次备份开始之前,一天的快照几乎无法通过线路传输。我们的发送/接收命令是:
zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | bzip2 -c | \
ssh offsite-backup "bzcat | zfs recv -F tank/vm"
我有大量的 CPU 周期可供使用。有没有更好的压缩算法或替代方法可以用来在线路上推送更少的数据?
我正在通过点对点 T1 线路发送增量 ZFS 快照,并且在下一次备份开始之前,一天的快照几乎无法通过线路传输。我们的发送/接收命令是:
zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | bzip2 -c | \
ssh offsite-backup "bzcat | zfs recv -F tank/vm"
我有大量的 CPU 周期可供使用。有没有更好的压缩算法或替代方法可以用来在线路上推送更少的数据?
自发布此问题以来,这些年来情况发生了变化:
1:ZFS 现在支持压缩复制,只需在 zfs send 命令中添加 -c 标志,并且在磁盘上压缩的块在通过管道到达另一端时将保持压缩状态。可能还有更多的压缩需要获得,因为 ZFS 中的默认压缩是 lz4
2:在这种情况下最好使用的压缩器是 zstd (ZStandard),它现在有一个“自适应”模式,可以根据zfs send 和 zfs recv 之间的链接速度。它会尽可能多地压缩,同时将等待流出管道的数据队列保持在最低限度。如果你的链接速度很快,它不会浪费时间压缩更多的数据,如果你的链接很慢,它会继续努力压缩数据,最终节省你的时间。它还支持线程压缩,因此我可以利用 gzip 和 bzip 不支持的多个内核,在 pigzip 等特殊版本之外。
这是我学到的与您正在做的完全相同的事情。我建议使用 mbuffer。在我的环境中进行测试时,它只对接收端有帮助,如果没有它,发送会在接收赶上时变慢。
一些例子: http ://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send-zfs-receive/
带有选项和语法的主页 http://www.maier-komor.de/mbuffer.html
我的复制脚本中的发送命令:
这会将远程主机上的 mbuffer 作为接收缓冲区运行,以便发送尽可能快地运行。我运行了一条 20mbit 的线路,发现在发送端也有 mbuffer 并没有帮助,而且我的主要 zfs 框正在使用它的所有 ram 作为缓存,所以即使给 mbuffer 1g 也需要我减少一些缓存大小。
另外,这不是我的专业领域,我认为最好让 ssh 进行压缩。在您的示例中,我认为您使用的是 bzip,然后使用默认使用压缩的 ssh,因此 SSH 正在尝试压缩压缩流。我最终使用 arcfour 作为密码,因为它是 CPU 密集度最低的,这对我来说很重要。使用另一种密码可能会有更好的结果,但我绝对建议让 SSH 进行压缩(或者如果你真的想使用它不支持的东西,请关闭 ssh 压缩)。
真正有趣的是,在 localhost 上发送和接收时使用 mbuffer 也会加快速度:
我发现用于 localhost 传输的 4g 似乎是我的最佳选择。它只是表明 zfs 发送/接收并不真正喜欢延迟或流中的任何其他暂停以最好地工作。
只是我的经验,希望对你有帮助。我花了一段时间才弄清楚这一切。
通过 WAN 发送时,我一直使用pbzip2 (并行 bzip2)。由于它是线程化的,因此您可以使用 -p 选项指定要使用的线程数。首先在发送和接收主机上安装 pbzip2,安装说明位于http://compression.ca/pbzip2/。
主要的关键是频繁地创建快照(约 10 分钟),以使您的快照大小更小,然后发送每个快照。ssh 不会从损坏的快照流中恢复,因此,如果您要发送巨大的快照,请将流传输到 pbzip2,然后拆分为可管理大小的块,然后 rsync 拆分文件到接收主机,然后传输到 zfs 接收连接的 pbzip2 文件。
这将生成以 500MB 块命名的文件:
rsync 到接收主机多次(您甚至可以在 zfs 发送完成之前或在看到完整的 500MB 块时立即进行 rsync),随时按ctrl+c取消:
zfs 收到:
用户朋友提到:为了它的价值。我不会直接发送| 压缩 | 解压 | 如果传输线卡住并且您的池将在接收期间长时间离线,这可能会导致接收端出现问题。- 如果正在进行的发送/接收被网络中断而中断,但没有达到池脱机的程度,我之前在接收主机中遇到过旧的 zfs 版本 <28 的问题。那很有意思。仅当“zfs recv”在接收端退出时才重新发送快照。如果需要,手动终止“zfs recv”。zfs send/recv 现在在 FreeBSD 或 Linux 中得到了很大改进。
这是对您的具体问题的回答:
您可以尝试rzip,但它的工作方式与 compress/bzip/gzip 有点不同:
rzip 期望能够读取整个文件,因此它不能在管道中运行。这将大大增加您的本地存储需求,并且您将无法运行备份并通过单一管道通过线路发送备份。也就是说,至少根据这个测试,生成的文件要小得多。
如果您的资源限制是您的管道,那么无论如何您都将运行 24x7 备份,因此您需要不断地复制快照并希望您能跟上。
您的新命令将是:
您将需要更好地纠正错误,并且您将需要考虑使用 rsync 之类的东西来传输压缩文件,这样如果传输在中间失败,您可以从中断的地方继续。
听起来您已经尝试了所有最好的压缩机制,但仍然受到线路速度的限制。假设运行更快的线路是不可能的,您是否考虑过不那么频繁地运行备份,以便它们有更多的时间运行?
除此之外,是否有某种方法可以降低写入的数据量?在不了解您的应用程序堆栈的情况下很难说如何,但只是做一些事情,例如确保应用程序覆盖现有文件而不是创建新文件可能会有所帮助。并确保您没有保存不需要的临时/缓存文件的备份。
我的经验是,
zfs send
尽管比接下来的压缩步骤快得多(平均而言),但它还是相当突然的。zfs send
我的备份在之后插入了相当多的缓冲gzip
:在我的情况下,输出设备是 USB(不是网络)连接的,但是由于类似的原因缓冲很重要:当 USB 驱动器保持 100% 忙碌时,整体备份时间会更快。您可能不会整体发送更少的字节(根据您的要求),但您仍然可以更快地完成。缓冲可防止受 CPU 限制的压缩步骤成为受 IO 限制的步骤。
物有所值。我不会直接发送| 压缩 | 解压 | 如果传输线卡住并且您的池将在接收期间长时间离线,这可能会导致接收端出现问题。我们发送到本地文件,然后 gzip 快照并使用 rsync(使用河床)传输,然后我们从文件中接收。河床不会优化交通,但如果传输出现问题并且需要重新启动,河床会加快重新发送的速度。
我们已经研究过不压缩增量快照,使用 Rsync 压缩并且不使用河床以外的任何压缩。很难说哪个最好,但是当我们使用 rsync 压缩从 oracle 传输归档日志时,传输速率大约是普通文件和河床(使用 RSync)的两倍。
如果您有河床,则使用 rsync 而不是 ssh,因为河床了解 rsync 并将尝试对其进行优化并将数据添加到缓存中(见上文,重新启动传输)。
您可以为 ssh 选择更快的密码,也许是 blowfish-cbc,也可以尝试使用 -123456789 开关
“最佳”压缩算法取决于您拥有的数据类型 - 如果您正在推送 MP3 集合压缩可能会减慢处理速度,而文本/日志文件可以使用
gzip -9
.你每天推送多少数据?
我假设您根本无法增加站点的原始带宽...
您可能会看到不在主机上使用压缩的好处。
如果您使用类似 wan 优化器的东西,如果您在发送文件之前不压缩文件,它将能够更好地优化传输,即您完全按照您正在做的事情,但从管道中删除 bzip2。运行几次备份后,wan 优化器将缓存它在传输中看到的大部分内容,您将看到传输速度的巨大改进。
如果您的预算有限,您可以通过使用 rsync 和 rsync未压缩的快照看到类似的改进,即:
这会更快,因为 rsync 只会传输昨天的快照和今天的快照之间的差异。根据快照过程的工作方式,两者之间可能仍然存在大量冗余,即使它们根本不是同一个文件。
到目前为止,wan 优化器是解决这个问题的一种更有可能的方法(好吧,metro ethernet 是解决这个问题的最有可能的方法,但我们将不讨论这个问题)。在编写光纤或河床安装的大检查之前,rsync 只是在您的本地数据上进行测试(在本地;rsync 会告诉您它在直接副本上节省了多少时间)的黑暗中的狂野镜头。