利用多核进行tar+gzip/bzip压缩/解压

我通常使用tar zcvf压缩并使用tar zxvf解压(由于习惯使用gzip)。

我最近买了一个带有超线程的四核CPU,所以我有8个逻辑内核,我注意到许多内核在压缩/解压期间没有使用。

有什么方法可以利用未使用的内核使它更快吗?

211636 次浏览

你可以使用pigz代替gzip,后者在多核上进行gzip压缩。而不是使用-z选项,你将通过pigz管道它:

tar cf - paths-to-archive | pigz > archive.tar.gz

默认情况下,pigz使用可用内核的数量,如果无法查询,则使用8个。你可以用-p n要求更多,例如-p 32。Pigz具有与gzip相同的选项,因此您可以使用-9请求更好的压缩。如。

tar cf - paths-to-archive | pigz -9 -p 32 > archive.tar.gz

你也可以使用tar标志"——use-compress-program="来告诉tar使用什么压缩程序。

例如:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip

你可以为tar的--use-compress-program开关使用快捷方式-I,并在多个核上调用pbzip2进行bzip2压缩:

tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/

常见的方法

tar程序有一个选项:

-I, --use-compress-program PROG
filter through PROG (must accept -d)

您可以使用多线程版本的存档或压缩实用程序。

最流行的多线程归档器是pigz(而不是gzip)和pbzip2(而不是bzip2)。例如:

$ tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 paths_to_archive
$ tar --use-compress-program=pigz -cf OUTPUT_FILE.tar.gz paths_to_archive

归档程序必须接受-d。如果你的替换工具没有这个参数并且/或者你需要指定额外的参数,那么使用管道(如果需要的话添加参数):

$ tar cf - paths_to_archive | pbzip2 > OUTPUT_FILE.tar.gz
$ tar cf - paths_to_archive | pigz > OUTPUT_FILE.tar.gz

单线程和多线程的输入输出兼容。您可以使用多线程版本进行压缩,使用单线程版本进行解压缩,反之亦然。

p7zip

对于p7zip进行压缩,你需要一个像下面这样的小shell脚本:

#!/bin/sh
case $1 in
-d) 7za -txz -si -so e;;
*) 7za -txz -si -so a .;;
esac 2>/dev/null

保存为7zhelper.sh。下面是用法示例:

$ tar -I 7zhelper.sh -cf OUTPUT_FILE.tar.7z paths_to_archive
$ tar -I 7zhelper.sh -xf OUTPUT_FILE.tar.7z

xz

关于多线程XZ支持。如果你运行的是5.2.0或更高版本的XZ Utils,你可以通过环境变量XZ_DEFAULTS(例如XZ_DEFAULTS="-T 0")将-T--threads设置为适当的值来利用多个内核进行压缩。

这是5.1.0alpha版本的人类片段:

多线程压缩和解压缩还没有实现,所以这个

.选项暂时无效

然而,这将不适用于未解压的文件 已启用线程压缩。从man版本5.2.2:

线程解压缩尚未实现。它只会起作用 在文件中包含多个大小信息的块 块头。所有在多线程模式下压缩的文件都符合这个要求 条件,但是在单线程模式下压缩的文件不会 ——block-size=size

使用替换重新编译

如果从源代码构建tar,则可以使用参数重新编译

--with-gzip=pigz
--with-bzip2=lbzip2
--with-lzip=plzip

在用这些选项重新编译tar之后,你可以检查tar帮助的输出:

$ tar --help | grep "lbzip2\|plzip\|pigz"
-j, --bzip2                filter the archive through lbzip2
--lzip                 filter the archive through plzip
-z, --gzip, --gunzip, --ungzip   filter the archive through pigz

如果你想在文件名和压缩选项上有更多的灵活性,你可以使用:

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec \
tar -P --transform='s@/my/path/@@g' -cf - {} + | \
pigz -9 -p 4 > myarchive.tar.gz

步骤1:find

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec

这个命令将查找你想要归档的文件,在本例中是/my/path/*.sql/my/path/*.log。添加任意数量的-o -name "pattern"

-exec将使用find: tar的结果执行下一个命令

步骤2:tar

tar -P --transform='s@/my/path/@@g' -cf - {} +

--transform是一个简单的字符串替换参数。它将从存档中剥离文件的路径,以便在提取时tarball的根目录成为当前目录。注意,你不能使用-C选项来更改目录,因为你将失去find的好处:该目录下的所有文件将被包括在内。

-P告诉tar使用绝对路径,因此它不会触发警告“从成员名中删除前导' /'”。不管怎样,以'/'开头的字符将被--transform删除。

-cf -告诉tar使用后面指定的tarball名称

{} +使用find之前找到的所有文件

步骤3:pigz

pigz -9 -p 4

使用任意多的参数。 在本例中,-9是压缩级别,-p 4是专用于压缩的内核数。 如果你在一个重载的web服务器上运行它,你可能不想使用所有可用的内核

步骤4:存档名称

> myarchive.tar.gz

最后。

你可能想要考虑的一个相对较新的压缩工具是zstandard。它在利用备用内核方面做得很好,并且在压缩比和(解)压缩时间方面做了一些很好的权衡。它还可以根据您的压缩比需求进行高度调整。