我通常使用tar zcvf
压缩和解压缩tar zxvf
(由于习惯使用gzip)。
我最近得到了一个带有超线程的四核 CPU,所以我有 8 个逻辑核心,我注意到许多核心在压缩/解压缩期间没有使用。
有什么办法可以利用未使用的内核使其更快?
您还可以使用 tar 标志“--use-compress-program=”来告诉 tar 使用什么压缩程序。
例如使用:
tar -c --use-compress-program=pigz -f tar.file dir_to_zip
您可以使用pigz代替 gzip,后者在多个内核上执行 gzip 压缩。您可以通过 pigz 管道而不是使用 -z 选项:
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
程序选项:
-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,您需要一个小的 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 Utils 5.2.0 或更高版本,您可以通过设置-T
或通过环境变量 XZ_DEFAULTS(例如)设置--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
您可以使用-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
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
使用绝对路径,因此它不会触发警告“从成员名称中删除前导 `/'”。--transform
无论如何都要删除前导“/” 。
-cf -
告诉tar
使用我们稍后指定的 tarball 名称
{} +
使用之前find
找到的每个文件
pigz
pigz -9 -p 4
使用尽可能多的参数。在这种情况下-9
是压缩级别,-p 4
是专用于压缩的核心数。如果你在负载很重的网络服务器上运行它,你可能不想使用所有可用的内核。
> myarchive.tar.gz
最后。
您可能要考虑的一个相对较新的(解)压缩工具是zstandard。它在利用备用内核方面做得非常出色,并且在压缩比与(去)压缩时间方面做了一些很好的权衡。它还可以根据您的压缩比需求进行高度调整。