是否rsync -z
在不考虑前一个文件的情况下压缩每个文件的块,或者是否为每个文件重置压缩字典以便独立处理?
例如,考虑一个可压缩文件one.txt
及其相同的副本被传输到远程服务器,其中两个文件都不存在:
cp -p one.txt two.txt
rsync -az one.txt two.txt remote:
Run Code Online (Sandbox Code Playgroud)
zlib
压缩层是否独立处理one.txt
和处理two.txt
,还是该级别的数据传输只是一个连续的流,因此它将学习一个有用的压缩字典,one.txt
以便它可以应用于two.txt
?
或者,我是否完全误解了zlib
压缩算法,例如(例如)总是为每个新块重置字典?
我试过查看rsync
调试输出,rsync -avvvvz --debug=IO1,IO2,IO3,IO4 --msgs2stderr
但看不到任何与压缩层特别相关的内容。
(这是对我在 ServerFault 上的一个答案的评论线程的跟进。)
rsync
在 中使用压缩token.c
,而且似乎只在那里使用。它在tx_strm
变量中维护 deflate 流状态,并send_deflated_token
在前一个标记为 -1 时重置流状态:
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);
Run Code Online (Sandbox Code Playgroud)
这是从使用match.c
,通过该match
功能,通过使用hash_search
和match_sums
。这些函数始终确保它们通过last_token
设置为 -1的调用完成处理,以便下一次调用将重置 deflate 流。所有这些都是逐个文件完成的,因此总是在每个文件的开头重置 deflate 流。
这意味着保证为每个文件重置块压缩字典;它可能会更频繁地重置。
如果rsync
要使用以前文件中的数据,则跨文件扩展其散列处理可能会更有趣。
您可以按照您的建议,通过同步可压缩文件的多个副本来实验性地验证所有这些;统计数据始终显示传输的大小等于单个文件的压缩大小乘以副本数,因此文件之间没有一种或另一种重复数据删除。