不使用 Gzip 压缩制作 Tar 归档文件速度能快多少? 不使用 Gzip 压缩制作 Tar 归档文件速度能快多少?

不使用 Gzip 压缩制作 Tar 归档文件速度能快多少?

关于 Gzip 和 Tar

Gzip 标志

LinuxBSD用户似乎都使用名为gzip 的程序,而且经常会配合另一个名为tar 的程序一起使用。tar的名称来源于 Tape Archive(磁带归档),它是一种将文件和文件夹(“目录”)复制到最初为磁带归档而设计的格式的程序。但 tar 归档文件除了可以保存到磁带之外,还可以保存到许多其他文件系统。例如,它可以保存到普通硬盘、固态硬盘、NVMe 硬盘等等。

创建压缩文件时,人们通常希望尽可能减小文件的大小。这时 gzip 就派上了用场。gzip 可以减小压缩文件的大小,从而节省存储空间。之后,可以将 gzip 压缩的 tar 文件“解压缩”。解压缩会将 tar 文件恢复到原始大小。在解压缩过程中,可以再次使用 tar 程序来“提取”或“解包”压缩文件。提取操作应该能够将压缩文件中的原始文件恢复到创建压缩文件时的状态。

除了用于长期存档之外,许多人也经常使用 tar 和 gzip 进行短期备份。例如,在我的服务器 Darkstar 上,我会编译和安装许多程序。在编译之前,我会使用 tar 创建一个短期备份,记录编译和安装之前的文件状态。

编写这份文件的三个好理由

首先,编译可以让我们获得程序的最新源代码。其次,编译几次之后,从最新源代码编译程序会比使用发行版的软件包管理器安装通常较旧的版本要容易得多。第三,自行编译可以让我们随时获取程序源代码。

我在 Darkstar 上编译的程序通常放在 /usr/local 目录下。在将新程序放入 /usr/local 之前,除了定期备份 Darkstar 之外,我还会创建一个 /usr/local 目录的存档,内容与添加新软件之前的状态完全一致。有了这个方便的 /usr/local 存档,如果在安装过程中出现任何问题,都可以轻松恢复到之前的状态。

创建预编译备份可能耗时过长

最近,随着添加到 /usr/local 中的软件越来越多,生成预编译归档文件所需的时间也越来越长,大约需要半个小时。

最近,我使用top(1) 命令观察了一个归档文件的生成过程。我注意到,在整个归档文件生成过程中,gzip 进程占用了一个 CPU 的 100%。

不使用 Gzip 压缩的普通 Tar 归档文件速度会快多少,体积会大多少?

我想知道如果不使用 gzip,预编译归档文件的总制作时间会有什么变化。我还想知道归档文件的大小会增大多少。下面展示了我发现的令人惊讶的制作时间差异的数据和分析。归档文件大小的差异也很大,但远不及制作时间的差异。

创建时间数据

我运行了两次预编译归档文件,一次使用 gzip 压缩,一次不使用 gzip 压缩。我分别对两次测试结果进行了逐行编号的记录。

000023 root@darkstar:/usr# time tar cvzf local-revert.tgz local
000024 local/
[ . . . ]
401625 local/include/gforth/0.7.3/config.h
401626
401627 real 28m11.063s
401628 user 27m1.436s
401629 sys 1m21.425s
401630 root@darkstar:/usr# time tar cvf local-revert.tar local
401631 local/
[ . . . ]
803232 local/include/gforth/0.7.3/config.h
803233
803234 real 1m14.494s
803235 user 0m4.409s
803236 sys 0m46.376s
803237 root@darkstar:/usr#

这篇Stack Overflow 帖子解释了 time(1) 命令返回的实际时间、用户时间和系统时间之间的区别。“实际”时间指的是系统时钟时间,因此它显示的是命令执行完成所花费的时间。

Gzip压缩耗时是原来的22倍!

这里我们可以看到,使用 gzip 压缩制作归档文件大约需要 28 分钟。而不使用 gzip 压缩制作归档文件仅需 1.25 分钟。使用 gzip 压缩的归档文件制作时间是未压缩归档文件的 22 倍!

存档大小数据

现在我们来检查一下存档大小。

root@darkstar:/usr# ls -lh local-revert.t*
-rw-r--r-- 1 root root 22G Oct 4 05:22 local-revert.tar
-rw-r--r-- 1 root root 10G Oct 4 05:20 local-revert.tgz
root@darkstar:/usr#

经过 gzip 压缩的归档文件大小为 10 GB,而未经压缩的 tar 归档文件大小为 22 GB。

Gzip 的压缩率为 55%。

压缩文件压缩了 55%。压缩率真高!

结论

Darkstar 上有充足的磁盘空间。因此,创建一个体积翻倍但创建速度提升 22 倍的归档文件可能是最佳选择。以后,在编译之前,我会在备份 /usr/local 时完全跳过任何压缩步骤,以便启用回滚功能。这样我就不用再等那半个小时了!

补充思考

创建时间和压缩包大小预计会因文件类型而异。例如,与 Darkstar 的 /usr/local 目录中的文件不同,许多图像文件格式本身已经过压缩,因此额外的压缩并不会显著减小其大小。

在准备这篇文章的过程中,我发现了pigz。Pigz (发音为“pig-zee”)是 gzip 的一种实现,它能够充分利用多核处理器的性能。也许不久之后,pigz 就会成为 Darkstar 的 /usr/local 目录下的新成员。

另一种提高压缩速度的方法是使用除 gzip 之外的其他压缩程序。有很多流行的压缩程序,例如 bzip2 和 xz。可以使用 tar 的 -I 选项调用这些其他压缩程序。

当然,用 tar 的 -I 选项更改压缩程序是一回事,让 tar 本身并行运行又是另一回事。这里有一篇Stack Exchange 上关于并行 tar 打包的帖子。我得试试。

最后,与我们分别获取源代码和编译后的程序不同,我们自己编译的源代码似乎就是我们实际运行的程序的源代码。然而,早在 1984 年,肯·汤普森就意识到,我们自己编译的程序有时可能与预期 大相径庭