压缩非常大(100G)文件的时间

压缩非常大(100G)文件的时间

我发现自己必须压缩大量非常大的文件(80 GB 左右),而我对系统表现出的速度(缺乏)感到惊讶。我的转换速度约为 500 MB/分钟;使用top,我似乎以大约 100% 的速度使用了单个 CPU。

我很确定这不仅仅是磁盘访问速度的问题,因为创建一个tar文件(这就是创建 80G 文件的方式)只花了几分钟(可能 5 分钟或 10 分钟),但 2 个多小时后我的简单 gzip 命令仍然没有完成。

总之:

tar -cvf myStuff.tar myDir/*

花费不到 5 分钟创建一个 87 G 的 tar 文件

gzip myStuff.tar

耗时2小时10分钟,创建了一个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

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

答案1

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

答案2

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

问题是 gzip 被限制(正如您所发现的)到单个线程。

进入,可以使用多个线程来执行压缩。如何使用它的示例如下:

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

上有一篇关于 --use-compress-program 选项的简洁摘要姊妹网站

答案3

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

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

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

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

答案4

我们还可以利用 pigz 中可用的进程数量,这通常具有更快的性能,如以下命令所示

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。

相关内容