使用多核心的tar + gzip / bzip压缩/解压

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

我最近得到了一个超线程的四核CPU,所以我有8个逻辑核心,我注意到许多核心在压缩/解压过程中没有被使用。

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

您可以使用pigz而不是gzip,它可以在多个核心上进行gzip压缩。 而不是使用-z选项,你可以通过pigz来pipe理它:

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

默认情况下,pigz使用可用内核的数量,如果不能查询,则为8。 你可以用-pn来请求更多,例如-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程序的选项:

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

您可以使用multithreading版本的归档器或压缩工具。

最stream行的multithreading归档器是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 

Archiver必须接受-d。 如果你的replace工具没有这个参数和/或你需要指定附加参数,那么使用pipe道(如果需要,添加参数):

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

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

的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

关于multithreadingXZ支持。 如果您正在运行XZ Utils的5.2.0或更高版本,则可以通过环境variablesXZ_DEFAULTS(例如XZ_DEFAULTS =“ – T 0”)将“-T”或“–threads”设置为适当的值。 这是5.1.0alpha版本的人的片段:

multithreading压缩和解压还没有实现,所以这个选项现在没有效果。

用replace重新编译

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

 --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 

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

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

如果您想要使用文件名和压缩选项更灵活,可以使用:

 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将使用findtar的结果执行下一个命令

第2步: tar

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

--transform是一个简单的stringreplace参数。 它将从档案中去除文件的path,所以当解压缩时,tarball的根目录变成当前目录。 请注意,您不能使用-C选项来更改目录,因为您将失去find好处:将包括该目录的所有文件。

-P告诉tar使用绝对path,所以它不会触发“从成员名称中删除前导'/'的警告。 领先的'/'被无论如何都被--transform

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

{} +使用之前find每个文件

第3步: pigz

pigz -9 -p 4

根据需要使用尽可能多的参数。 在这种情况下, -9是压缩级别, -p 4是专用于压缩的核心数量。 如果你在一个重载的web服务器上运行这个,你可能不想使用所有可用的内核。

第4步:存档名称

> myarchive.tar.gz

最后。

上面的熊基米奥夫提出的解决scheme很好。 我刚刚用.tar.bz2备份了我的笔记本电脑,只用了一个cpu线程就花了132分钟。 然后我从源代码编译并安装tar:

https://www.gnu.org/software/tar/

我包括configuration步骤中提到的选项:

./configure –with-gzip = pigz –with-bzip2 = lbzip2 –with-lzip = plzip

我再次运行备份,只花了32分钟。 这比4倍的改善更好! 我观察了系统监视器,并保持全部4个cpus(8个线程)在整个时间100%平整。

这是最好的解决scheme。