rsync 块压缩字典是否为每个文件重置?

roa*_*ima 6 compression rsync

是否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 上的一个答案的评论线程的跟进。)

Ste*_*itt 6

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_searchmatch_sums。这些函数始终确保它们通过last_token设置为 -1的调用完成处理,以便下一次调用将重置 deflate 流。所有这些都是逐个文件完成的,因此总是在每个文件的开头重置 deflate 流。

这意味着保证为每个文件重置块压缩字典;它可能会更频繁地重置。

如果rsync要使用以前文件中的数据,则跨文件扩展其散列处理可能会更有趣。

您可以按照您的建议,通过同步可压缩文件的多个副本来实验性地验证所有这些;统计数据始终显示传输的大小等于单个文件的压缩大小乘以副本数,因此文件之间没有一种或另一种重复数据删除。