改善大量重复内容文件的 tarball 压缩效率

• 本文约 658 字,阅读大致需要 2 分钟 | Cheatsheets | #tarball | #xz | #Compression | #hardlink | #tar | #文件压缩

有时,我们会希望分发包含大量重复文件的tarball。绝大多数情况下,tarball都会进行压缩,进行适当的预处理有助于显著地提高压缩效率。

数据压缩的基本原理是利用数据中的冗余,通过更短的编码或规则表示重复或可预测的内容,从而减少存储或传输所需的空间。简单的例子中,比如连续重复的字符「AAAAAA」可以表达为「6A」,然而,当重复数据分布在较长范围内时,压缩算法很难直接发现和利用这些远距离的关联,因为需要额外记录位置或匹配信息,这种匹配开销很大,做的话会严重影响压缩速度并且可能收益不高。对于文本文件来说,其中的许多内容会高频率地出现,而如果一个tarball中包括数个内容一样的大型二进制文件,压缩算法很难有效地检测并对他们进行正确的处理。

但是,tar (pax) 格式本身内建了对硬连接的支持。在表达硬连接时,tar会使用 typeflag 1来表示,而不是再次存储同一文件的内容。这样一来,一个比较明显的思路就是在打包前把整个目录中所有内容一样的文件先转换成硬连接。这件事有一个现成的工具是Julian Andres Klode的 hardlink(1),它会扫描整个目录,把大小一样的文件进行比较,并把这些文件转换为硬连接。

另一个值得考虑的事情是把文件名类似的文件放在一起。这个做法的实质是尽量把内容类似的文件放到一起,例如如果我们在打一个包含若干同一套软件的不同版本的源代码tarball的时候,如果两个文件名字一样,那么他们的内容很可能高度相似,因此把这些文件放到一起也有助于提高压缩效率。

最后是丢弃一些信息,例如文件的修改日期(例如把它设置为0)。这会给tarball中增加许多重复的0,利于压缩。