是否rsync -z
压缩每个文件的块而不考虑前一个文件,或者是否为每个文件重置压缩字典以便独立处理?
作为一个例子,考虑一个可压缩文件one.txt
及其相同的副本被传输到远程服务器,其中两个文件都不存在:
cp -p one.txt two.txt
rsync -az one.txt two.txt remote:
压缩层是否独立zlib
处理one.txt
和two.txt
,或者该级别的数据传输只是一个连续流,因此它将学习一个one.txt
可以应用的有用的压缩字典two.txt
?
或者,我是否完全误解了zlib
压缩算法,例如(例如)总是为每个新块重置字典?
我尝试查看rsync
调试输出rsync -avvvvz --debug=IO1,IO2,IO3,IO4 --msgs2stderr
,但看不到任何与压缩层特别相关的内容。
(这是后续评论区根据我在 ServerFault 上的回答。)
答案1
rsync
使用压缩token.c
,而且似乎只有那里。它在变量中维护 deflate 流状态,并在前一个标记为 -1 时tx_strm
重置流状态:send_deflated_token
if (last_token == -1) {
/* initialization */
if (!init_done) {
tx_strm.next_in = NULL;
tx_strm.zalloc = NULL;
tx_strm.zfree = NULL;
if (deflateInit2(&tx_strm, compression_level,
Z_DEFLATED, -15, 8,
Z_DEFAULT_STRATEGY) != Z_OK) {
rprintf(FERROR, "compression init failed\n");
exit_cleanup(RERR_PROTOCOL);
}
if ((obuf = new_array(char, OBUF_SIZE)) == NULL)
out_of_memory("send_deflated_token");
init_done = 1;
} else
deflateReset(&tx_strm);
这是使用自match.c
,通过该match
函数,由hash_search
和使用match_sums
。这些函数始终确保它们通过将设置为 -1 的调用完成处理last_token
,以便下一次调用将重置 deflate 流。所有这些都是逐个文件完成的,因此 deflate 流始终在每个文件的开头重置。
这意味着保证为每个文件重置块压缩字典;它可能会更频繁地重置。
如果rsync
要使用以前文件中的数据,跨文件扩展其哈希处理可能会更有趣。
您可以按照您的建议通过同步可压缩文件的多个副本来实验验证所有这些;统计数据始终显示传输的大小等于单个文件的压缩大小乘以副本数,因此跨文件不存在某种类型的重复数据删除。