利用多核进行 tar+gzip/bzip 压缩/解压缩
Posted
技术标签:
【中文标题】利用多核进行 tar+gzip/bzip 压缩/解压缩【英文标题】:Utilizing multi core for tar+gzip/bzip compression/decompression 【发布时间】:2012-09-01 01:12:22 【问题描述】:我通常使用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 个 CPU(8 个线程)始终保持在 100% 的状态。这是最好的解决方案。 【参考方案1】:您可能要考虑的一个相对较新的(解)压缩工具是zstandard。它在利用备用内核方面做得非常出色,并且在压缩比与(去)压缩时间方面做了一些很好的权衡。它还可以根据您的压缩比需求进行高度调整。
【讨论】:
【参考方案2】:常用方法
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 支持。如果您运行的是 XZ Utils 5.2.0 或更高版本,您可以通过环境变量 XZ_DEFAULTS(例如 XZ_DEFAULTS="-T 0"
)将 -T
或 --threads
设置为适当的值来利用多个内核进行压缩。
这是 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
【讨论】:
这确实是最好的答案。我一定会重建我的焦油! 我刚刚找到了pbzip2 和mpibzip2。 mpibzip2 看起来非常适合集群,或者如果您有一台笔记本电脑和一台多核台式机。 这是一个伟大而详尽的答案。值得一提的是,多线程压缩(例如使用pigz
)仅在从文件中读取时才启用。处理 STDIN 实际上可能更慢。
xz
选项加 1。这是最简单但有效的方法。
export XZ_DEFAULTS="-T 0"
在调用 tar
之前使用选项 -J
进行 xz 压缩就像一个魅力。【参考方案3】:
如果您希望文件名和压缩选项更灵活,您可以使用:
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
第一步:find
find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec
此命令将查找您要归档的文件,在本例中为 /my/path/*.sql
和 /my/path/*.log
。添加任意数量的-o -name "pattern"
。
-exec
将使用find
的结果执行下一条命令:tar
第二步:tar
tar -P --transform='s@/my/path/@@g' -cf - +
--transform
是一个简单的字符串替换参数。它将从存档中删除文件的路径,以便在解压缩时将 tarball 的根目录变为当前目录。请注意,您不能使用-C
选项来更改目录,因为您将失去find
的好处:将包含目录的所有文件。
-P
告诉tar
使用绝对路径,因此它不会触发警告“Removingleading `/' from member names”。前导 '/' 无论如何都会被 --transform
删除。
-cf -
告诉tar
使用我们稍后会指定的压缩包名称
+
使用 find
之前找到的所有文件
第三步:pigz
pigz -9 -p 4
使用尽可能多的参数。
在这种情况下,-9
是压缩级别,-p 4
是专用于压缩的核心数。
如果你在负载很重的网络服务器上运行它,你可能不想使用所有可用的内核。
第 4 步:存档名称
> myarchive.tar.gz
终于。
【讨论】:
【参考方案4】:您可以使用快捷方式 -I
来切换 tar 的 --use-compress-program
开关,并调用 pbzip2
来在多核上进行 bzip2 压缩:
tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/
【讨论】:
一个不错的 TL;@MaximSuslov 的 answer 的 DR。 返回tar: home/cc/ziptest: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors
`【参考方案5】:
您可以使用pigz 代替 gzip,后者在多个内核上进行 gzip 压缩。您可以通过 pigz 管道而不是使用 -z 选项:
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
【讨论】:
如何使用 pigz 以同样的方式解压?还是只适用于压缩? pigz 确实使用多核进行解压,但对单核的改进有限。 deflate 格式不适合并行解压缩。解压部分必须连续进行。 pigz 解压的其他核用于读取、写入和计算 CRC。另一方面,当压缩时,pigz 接近 n 个核心的 n 改进因子。 这里的连字符是stdout(见this page)。 是的。双向 100% 兼容。 实际上没有 CPU 时间花费在 tarring 上,所以它没有多大帮助。 tar 格式只是输入文件的副本,文件之间有头块。【参考方案6】:您还可以使用 tar 标志“--use-compress-program=”来告诉 tar 使用什么压缩程序。
例如使用:
tar -c --use-compress-program=pigz -f tar.file dir_to_zip
【讨论】:
这是一个很棒的小知识点,值得更多的支持。我什至不知道这个选项存在,这些年来我已经阅读了几次手册页。 @Valerioschiavoni:不在这里,我在所有 4 个内核上都满负荷运行(Ubuntu 15.04 'Vivid')。 我更喜欢tar - dir_to_zip | pv | pigz > tar.file
pv 帮我估计,你可以跳过。但仍然更容易书写和记忆。
@NathanS.Watson-Haigh 是的。只需将程序名称和参数括在引号中即可。 man tar
这么说,this 也是这么说的。
2020 年,zstd
是最快的工具。压缩和解压缩时显着加速。使用tar -cf --use-compress-program=zstdmt
来实现多线程。以上是关于利用多核进行 tar+gzip/bzip 压缩/解压缩的主要内容,如果未能解决你的问题,请参考以下文章