通过慢速链接同步大型文件时,使用增量压缩通常很有用,以减少所用的带宽。压缩文件也很有用,因为它们占用的空间要小得多。
然而,许多压缩算法会产生不良的副作用,即当源中仅做了很小的更改时,压缩输出的大部分内容会发生变化。
那么,有哪些压缩算法/实用程序可以从类似的源文件创建类似的压缩 blob?
答案1
您可能需要考虑使用--rsyncable gzip 参数。这会稍微降低压缩率,因为它会在 tarball 中每个文件的开头重置压缩算法。
但请注意,您也可以使用 rsync 的 -z 选项来压缩传输的数据。如果您愿意未压缩源和目标上的文件,这可能足以满足您的需要。
我们使用它来同步大约 20 GB 的压缩 MySQL 数据库备份。使用 gzip --rsyncable,如果我们已经拥有前一天的快照,我们通常只能通过 rsync 传输一小部分压缩文件。我还没有尝试传输未压缩的 tar 文件并使用 rsync 的 -z 选项,所以我无法评论它的相对效率。
答案2
一种解决方案是手动逐块压缩文件。使用以下脚本进行简单测试后,文件大小仅略大(~0.1%),块大小为 1MiB。它适用于支持连接的算法(gzip 和 bzip2 就是其中两个)。它也稍慢一些,但很容易并行化。
#!/bin/bash
alg="${2:-gzip}"
size=$(stat -c %s "$1")
cur=0
block=$((1024*1024)) # 1M blocks.
while [ $cur -lt $size ]; do
#echo $alg $size $block $cur >&2
tail -c +$cur "$1" | head -c $block | $alg
cur=$((cur+block))
done
这样,更改只会影响更改的块。
答案3
您可能需要考虑使用差分. 它类似于同步但它不需要与服务器建立双向连接。
你的使用方式是
- 在源计算机上:
rdiff signature file.ext file.ext.sig
这将创建一个签名文件,其中包含将来差异将使用的块的哈希值。将 .sig 文件保留在源计算机上。 - 正常压缩文件并发送到目的地
- 在目标位置解压文件
- 时间流逝
- 在源计算机上:
rdiff delta file.ext.sig file.ext file.ext.delta
这将创建一个增量文件,其中仅包含哈希值与签名文件不匹配的更改。- 您可能会做另一次操作
rdiff signature file.ext file.ext.sig
来更新签名文件。
- 您可能会做另一次操作
- 将增量文件发送到目标,增量文件已经压缩
- 在目标上:
rdiff patch file.ext file.ext.delta file.ext
这将更新文件的目标副本以匹配源副本。根据 rdiff 的构建,第二个参数和第四个参数可能需要不同的文件名。