是时候压缩非常大的(100G)文件了


27

我发现自己不得不压缩许多非常大的文件(80-ish GB),并且我对我的系统表现出的(缺乏)速度感到惊讶。我得到大约500 MB / min的转换速度;使用top,我似乎正在以大约100%使用单个CPU。

我非常确定这不是(只是)磁盘访问速度,因为创建tar文件(这就是80G文件的创建方式)仅花费了几分钟(也许5或10),但是经过2个小时多之后,我仍然使用了简单的gzip命令未完成。

综上所述:

tar -cvf myStuff.tar myDir/*

用了不到5分钟的时间创建了87 G tar文件

gzip myStuff.tar

花了两个小时又十分钟,创建了一个55G的zip文件。

我的问题:这正常吗?有某些选择gzip可以加快速度吗?串联命令并使用会更快tar -cvfz吗?只见参考pigz- GZip压缩的并行实现 -但不幸的是我不能安装我使用的机器上的软件,所以这不是我的选择。例如,参见前面的问题

我打算自己尝试其中一些选项并为它们计时-但是,我很可能不会碰到选项的“魔术组合”。我希望这个网站上的某人知道加快速度的正确方法。

当我获得其他试验的结果时,我将更新此问题-但如果有人有特别好的技巧,我将非常感激。也许gzip只是花费了比我意识到更多的处理时间...

更新

按照承诺,我尝试了以下建议的技巧:更改压缩量,并更改文件的目标。对于大约4.1GB的tar,我得到以下结果:

flag    user      system   size    sameDisk
-1     189.77s    13.64s  2.786G     +7.2s 
-2     197.20s    12.88s  2.776G     +3.4s
-3     207.03s    10.49s  2.739G     +1.2s
-4     223.28s    13.73s  2.735G     +0.9s
-5     237.79s     9.28s  2.704G     -0.4s
-6     271.69s    14.56s  2.700G     +1.4s
-7     307.70s    10.97s  2.699G     +0.9s
-8     528.66s    10.51s  2.698G     -6.3s
-9     722.61s    12.24s  2.698G     -4.0s

所以是的,将标志从默认-6更改为最快可以-1使我提高30%的速度(对于我的数据)几乎不会更改zip文件的大小。无论我使用的是同一块磁盘还是另一块磁盘,本质上都没有区别(我必须多次运行才能获得任何统计意义)。

如果有人感兴趣,我将使用以下两个脚本生成这些计时基准:

#!/bin/bash
# compare compression speeds with different options
sameDisk='./'
otherDisk='/tmp/'
sourceDir='/dirToCompress'
logFile='./timerOutput'
rm $logFile

for i in {1..9}
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $sameDisk $logFile
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $otherDisk $logFile
done

第二个脚本(compressWith):

#!/bin/bash
# use: compressWith sourceDir compressionFlag destinationDisk logFile
echo "compressing $1 to $3 with setting $2" >> $4
tar -c $1 | gzip -$2 > $3test-$2.tar.gz

需要注意的三件事:

  1. 使用/usr/bin/time而不是time,因为的内置命令bash比GNU命令具有更少的选项
  2. 我没有打扰使用该--format选项,尽管这样会使日志文件更易于阅读
  3. 我使用了脚本编写脚本,因为time似乎只能对管道序列中的第一个命令进行操作(因此我使它看起来像一个命令...)。

通过所有这些学习,我的结论是

  1. -1标志加快速度(可接受的答案)
  2. 与从磁盘读取数据相比,花在压缩数据上的时间要多得多
  3. 投资更快的压缩软件(pigz似乎是一个不错的选择)。
  4. 如果您有多个文件要压缩,则可以将每个gzip命令放在自己的线程中,并使用更多可用的CPU(可怜的人pigz

感谢所有帮助我学习这一切的人!


tar -cvf不做任何压缩,因此会更快
parkydr

2
@Floris:您要压缩哪种数据?旁注:$> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gz将显示您的计算机压缩内容的速度。side-note2:将结果存储到另一张光盘上。
akira

3
抱歉,我看不懂你的问题。gzip具有--fast选项以选择最快的压缩率
parkydr,

1
@parkydr:--fast选项是我不知道的一个...这是man页面中的最后一个,我还没读完(因为它是按“单字母命令”排序的,即-#) 。那会教我RTFM!这将是我接下来尝试的事情!
弗洛里斯

2
请注意,如果计算机上有合适的编译器可用,并且未将文件系统权限设置为禁止从您有权访问的目录中执行二进制文件,则可以pigz从碰巧构建它的位置编译并运行它,而无需安装它。如果没有编译器,则可以在另一台计算机上对其进行交叉编译,尽管这开始花费更多的精力,而不是值得的。(我猜这取决于您需要多大的压缩才能更快地运行。)
David Z

Answers:


27

您可以使用--fast --best或更改gzip的速度,-#其中#是1到9之间的数字(1最快但压缩率较低,9最快但压缩率较高)。默认情况下,gzip的运行级别为6。


26

tar与gzip相比花费的时间少的原因是,将文件复制到单个文件中的计算量很小(这就是它的作用)。另一方面,gzip实际上是使用压缩算法来缩小tar文件。

问题是gzip被约束(如您所发现的)到单个线程。

输入Pigz,它可以使用多个线程来执行压缩。如何使用它的一个例子是:

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

姊妹站点 --use-compress-program选项的简短摘要。


感谢您的回答和链接。我实际上在问题中提到了Pigz。
弗洛里斯

这是这里的正确答案。
stolsvik '16

4

我似乎正在以大约100%使用单个CPU。

这意味着没有I / O性能问题,但是压缩仅使用一个线程(gzip就是这种情况)。

如果您设法获得安装其他工具所需的访问/协议,那么7zip也支持多线程以利用多核CPU,尽管我不确定这是否扩展到gzip格式及其本身。

如果您暂时只使用gzip压缩并且有多个文件要压缩,则可以尝试单独压缩它们-这样一来,您将通过并行运行多个进程来使用更多的多核CPU。但是请注意不要过度使用它,因为一旦您接近I / O子系统的容量,性能就会急剧下降(低于使用一个进程/线程的性能),因为磁头移动的延迟变得非常重要。瓶颈。


感谢您的输入。您给了我一个主意(为此,您将获得一个赞):由于我要创建多个存档,因此我可以只编写单个命令,后跟一个&-然后让系统从那里开始处理它。每个压缩包都将在其自己的处理器上运行,并且由于我花在压缩上的时间比在I / O上花费的时间要多得多,因此与压缩10个压缩包相比,花费相同的时间进行压缩。因此,我从单线程可执行文件中获得了“多核性能” ...
Floris

1

人们可以利用pigg中可用的进程数量,这通常可以提高性能,如以下命令所示

tar cf-存档目录| Pigz -0 -p largenumber> mydir.tar.gz

示例-tar cf-patha | Pigz -0 -p 32> patha.tar.gz

这可能比帖子中建议的方法快,因为-p是一个可以运行的进程数。以我个人的经验,如果要归档的目录包含大量小文件,则设置一个很大的值不会影响性能。否则,默认值是8。对于大文件,我的建议是将此值设置为系统支持的线程总数。

如果使用32 CPU的计算机,则设置p = 32的值的示例会有所帮助。

0表示最快的Pigz压缩,因为它不压缩档案,而是专注于速度。压缩默认值为6。

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.