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


225

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

我最近获得了带有超线程的四核CPU,因此我有8个逻辑核,而且我注意到在压缩/解压缩过程中许多核没有使用。

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


上面的熊加亚莫夫提出的解决方案效果很好。我刚刚用.tar.bz2备份了笔记本电脑,仅用一个cpu线程花费了132分钟。然后,我从以下源代码编译并安装了tar:gnu.org/software/tar我包括了配置步骤中提到的选项:./ configure --with-gzip = pigz --with-bzip2 = lbzip2 --with-lzip = plzip我再次运行备份,只用了32分钟。这比4倍的改进要好!我看着系统监视器,它始终使所有4个cpus(8个线程)保持100%平坦。那是最好的解决方案。
沃伦·塞韦林

Answers:


309

您可以使用Pigz代替gzip,后者可以在多个内核上进行gzip压缩。除了使用-z选项,您还可以通过Pigz传递它:

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

默认情况下,pigz使用可用核心数,如果无法查询,则使用八个。您可以使用-pn来请求更多,例如-p32。pigz与gzip具有相同的选项,因此您可以使用-9请求更好的压缩。例如

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

3
您如何使用Pigz以相同的方式解压缩?还是仅适用于压缩?
user788171 2013年

42
Pigz确实使用了多个核心进行解压缩,但仅对单个核心进行了有限的改进。放气格式不适合并行解压缩。减压部分必须连续进行。Pigz解压缩的其他核心用于读取,写入和计算CRC。当另一方面压缩,pigz得到接近的因素ñ与改善ñ核心。
Mark Adler

7
此处的连字符为stdout(请参阅本页)。
加勒特2014年

3
是。双向兼容100%。
Mark Adler

4
实际上,没有花费CPU时间来处理时间,所以它并没有太大帮助。tar格式只是输入文件的副本,文件之间带有标题块。
Mark Adler

324

您也可以使用tar标志“ --use-compress-program =”来告诉tar使用哪种压缩程序。

例如使用:

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

21
这是一个很棒的知识点,值得更多的批评。我什至不知道这个选项是否存在,这些年来,我已经阅读过几次手册页。
Randall Hunt 2013年

2
@ValerioSchiavoni:不在这里,我在所有4个内核上都满负荷工作(Ubuntu 15.04'Vivid')。
bovender

8
我更喜欢tar - dir_to_zip | pv | pigz > tar.file光伏帮助我估算,您可以跳过它。但是仍然更容易编写和记忆。
Offenso

@ NathanS.Watson-Haigh是的。只需将程序名称和参数括在引号中即可。man tar这么说,象这样
Marc.2377

1
在2020年,这zstd是最快的工具。压缩和解压缩时的明显加速。用于tar -cf --use-compress-program=zstdmt多线程。
jadelord

112

常用方法

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

z

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

这是5.1.0alpha版本的man片段:

多线程压缩和解压缩尚未实现,因此此选项目前无效。

但是,这对于解压缩尚未通过启用线程进行压缩的文件不起作用。从5.2.2版的man中:

线程解压缩尚未实现。它仅适用于包含多个块且文件标题中包含大小信息的文件。在多线程模式下压缩的所有文件都满足此条件,但是即使使用--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

1
这确实是最好的答案。我一定会重建我的焦油!

1
我刚刚找到了pbzip2mpibzip2。对于群集,或者如果您有一台笔记本电脑和一台多核台式计算机,mpibzip2看起来非常有前途。

这是一个很好而详尽的答案。最好提及多线程压缩(例如,带有pigz)仅在从文件读取时才启用。实际上,处理STDIN可能会更慢。
oᴉɹǝɥɔ

3
加1作为xz选择。这是最简单但有效的方法。
selurvedu

2
export XZ_DEFAULTS="-T 0"tar使用-Jxz压缩选项进行调用之前,它就像是一种魅力。
scai

13

您可以将快捷方式-I用于tar的--use-compress-program切换,并pbzip2在多个内核上调用bzip2压缩:

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

一个不错的TL; DR,用于@MaximSuslov的答案
einpoklum

这将返回tar: home/cc/ziptest: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors`
Arash

1

如果要在文件名和压缩选项方面具有更大的灵活性,可以使用:

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是一个简单的字符串替换参数。它将从存档中剥离文件的路径,以便压缩包的根成为提取时的当前目录。请注意,您不能使用-Coption来更改目录,因为您将失去的好处find:将包含目录的所有文件。

-P告诉tar您使用绝对路径,因此不会触发警告“从成员名称中删除开头的'/'”。开头的“ /”始终被删除--transform

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

{} +使用find以前找到的每个文件

第三步: pigz

pigz -9 -p 4

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

步骤4:封存名称

> myarchive.tar.gz

最后。


0

您可能要考虑使用的相对较新的(解压缩)压缩工具是zstandard。它在利用备用内核方面做得非常出色,并且在压缩率与(解压缩)时间之间进行了一些权衡。它也可以根据您的压缩率需求进行高度调整。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.