bzip2太慢。多核可用


31

我正在运行以下命令:

pg_dumpall | bzip2 > cluster-$(date --iso).sql.bz2

太久了 我用看一下过程top。bzip2进程占用一个内核的大约95%和postgres 5%。该wa条目是低的。这意味着磁盘不是瓶颈。

我该怎么做才能提高性能?

也许让bzip2使用更多的内核。服务器具有16个核心。

还是使用bzip2的替代品?

我该怎么做才能提高性能?


8
除非出于传统原因需要bzip2,否则根据我的个人经验,xz比bzip2提供更好的压缩/时间。如果您有足够新的程序,它也会被线程化,并且可以根据需要将时间和内存使用量从gzipish扩展到大量。
珀金斯

6
“ pigz”是另一个选项-它产生gzip输出而不是bzip2输出。基本上,所有内容都可以理解gzip。
Criggie's

您可以尝试使用带有bzip2压缩的GnuPG对称地对其进行加密;由于某些未知的原因,即使仅以最高压缩级别进行压缩,与仅对其进行压缩相比,它似乎也具有惊人的速度。该算法可能比我的常规压缩程序(基于GUI)的效率更快。
Shule

2
您尚未说明替代算法的要求。Bzip2是可拆分的。这对您重要吗?
马丁·史密斯

7
我该怎么做才能提高性能? ”-不压缩它?您实际上并没有说需要对其进行压缩,并且不做事总是比做事快。使磁盘成为瓶颈。
TessellatingHeckler

Answers:


49

周围有很多压缩算法,并且bzip2是较慢的算法之一。平原gzip趋向于明显更快,而压缩通常不会差很多。当速度最重要时,这lzop是我的最爱。压缩效果不佳,但是太快了。

我决定找点乐子,比较一些算法,包括它们的并行实现。输入文件是pg_dumpall我的工作站上命令的输出,一个1913 MB的SQL文件。硬件是较旧的四核i5。时间就是压缩的挂钟时间。并行实现被设置为使用所有4个内核。表按压缩速度排序。

Algorithm     Compressed size        Compression          Decompression

lzop           398MB    20.8%      4.2s    455.6MB/s     3.1s    617.3MB/s
lz4            416MB    21.7%      4.5s    424.2MB/s     1.6s   1181.3MB/s
brotli (q0)    307MB    16.1%      7.3s    262.1MB/s     4.9s    390.5MB/s
brotli (q1)    234MB    12.2%      8.7s    220.0MB/s     4.9s    390.5MB/s
zstd           266MB    13.9%     11.9s    161.1MB/s     3.5s    539.5MB/s
pigz (x4)      232MB    12.1%     13.1s    146.1MB/s     4.2s    455.6MB/s
gzip           232MB    12.1%     39.1s     48.9MB/s     9.2s    208.0MB/s
lbzip2 (x4)    188MB     9.9%     42.0s     45.6MB/s    13.2s    144.9MB/s
pbzip2 (x4)    189MB     9.9%    117.5s     16.3MB/s    20.1s     95.2MB/s
bzip2          189MB     9.9%    273.4s      7.0MB/s    42.8s     44.7MB/s
pixz (x4)      132MB     6.9%    456.3s      4.2MB/s     7.9s    242.2MB/s
xz             132MB     6.9%   1027.8s      1.9MB/s    17.3s    110.6MB/s
brotli (q11)   141MB     7.4%   4979.2s      0.4MB/s     3.6s    531.6MB/s

如果服务器的16个内核足够闲置,可以全部用于压缩,pbzip2则可能会大大提高速度。但是您仍然需要更高的速度,并且可以容忍〜20%的较大文件,gzip这可能是您最好的选择。

更新:我将brotli结果添加到表中(请参见TOOGAM的答案)。brotli小号压缩质量设置对压缩率和速度非常大的影响,所以我添加三个设置(q0q1,和q11)。默认值为q11,但是它非常慢,并且仍然比差xzq1看起来很好;与相同的压缩率gzip,但是快4-5倍!

更新:向表中添加了lbzip2(请参见gmathts注释)和zstd(约翰尼的注释),并按压缩速度对其进行了排序。压缩速度是强大压缩比率的三倍,从而lbzip2使bzip2家庭恢复正常运行pbzip2zstd看起来也很合理,但是brotli (q1)在比率和速度上都被击败。

我最初认为平原gzip是最好的选择的结论开始显得几乎很愚蠢。虽然无处不在,但仍然无法击败;)


1
有关具有更多算法的类似表格,请参见mattmahoney.net/dc/text.html
Dougal

1
@道格拉斯公平。我的测试虽然是与OP相似的数据(pg_dumpall输出),所以可能更具代表性:)
marcelm

1
zstd是表中缺少的另一个-在压缩日志文件时,我发现单核zstd进程在压缩率相当的情况下胜过pbzip2的16个核。
约翰尼

1
lz4lzop顺便说一句,它比稍微更快,更高效。但是它使用更多的RAM,这在嵌入式系统中很重要。
Daniel B

1
如果您愿意测试多线程版本,也可以尝试zstd -T4。对于非常快速的设置,您可以尝试zstd -T4 -1zstd默认将-3其设置为,这可能是您测试过的设置。
青色

37

使用pbzip2。

手册说:

pbzip2是bzip2块排序文件压缩器的并行实现,该压缩器使用pthreads并在SMP机器上实现了近乎线性的加速。此版本的输出与bzip2 v1.0.2或更高版本完全兼容(即:任何使用pbzip2压缩的文件都可以使用bzip2解压缩)。

它会自动检测您拥有的处理器数量并相应地创建线程。


如果您正在压缩文件,那就很好了,尽管它可以通过管道进行可怕的工作
camelccc

@camelccc为什么这么说?我完全不是那样。您需要在其前面的管道上需要一个快速生成器或较大的缓冲区,以实现最佳性能,但这同样适用于管道pixzpigz管道。
Michael-sqlbot

取决于他要压缩的大小。如果您有一个较大的缓冲区,那就像您所说的那样很好,如果您要传递比物理内存大得多的东西,我发现事情会变得更加有趣。就像您说的那样,任何压缩算法都可能适用。
camelccc

4
bzip2可以使用相当多的ram,因此一次运行16个bzip worker可能会消耗超过1GB的不重要的ram。顺便说一句,BTW lbzip2似乎比提供了更好的速度,内存使用率和略微更好的压缩pbzip2。这里有基准:vbtechsupport.com/1614
gmatht

@gmatht lbzip2看起来不错!我将其添加到答案中:)
marcelm

8

您没有提到操作系统。如果是Windows,则带有ZStandard的7-Zip(发布)是7-Zip的版本,已被修改以提供对使用所有这些算法的支持。


有趣的是,我以前听说brotli过,但是我忘记了。我在回答中将其添加到基准表中!实际上,我对它的性能有些失望,除了在质量设置1下,它提供了与gzip更高速度相同的压缩率。
marcelm

2

使用zstd。如果对Facebook足够好,那么对您也可能足够好。

更严重的是,它实际上还不错。我现在将它用于所有事物,因为它可以正常工作,并且它可以使您大规模地以速度换取比率(大多数情况下,速度要比大小重要得多,因为存储便宜,但是速度是瓶颈)。
在达到与bzip2相当的总体压缩率的压缩级别上,它的速度要快得多,并且如果您愿意付出更多的CPU时间,则几乎可以达到与LZMA相似的结果(尽管这样做会比bzip2慢)。在压缩率稍差的情况下,它比bzip2或任何其他主流替代方法快得多,而且快得多。

现在,您正在压缩一个SQL转储,这对于压缩来说简直令人尴尬。即使是最贫穷的压缩器,在此类数据上的得分也很高。
因此,您可以zstd以较低的压缩级别运行,这将使运行速度提高数十倍,并且仍然可以在该数据上实现95-99%的相同压缩。

另外,如果您经常这样做并且想花一些额外的时间,则可以zstd提前“培训” 压缩机,从而提高压缩率和速度。请注意,为了使培训顺利进行,您需要向其提供单独的记录,而不是整个记录。该工具的工作方式是,期望有许多小的且有点相似的样本用于训练,而不是一个巨大的斑点。


更好的是,在多核计算机上使用pzstd(并行版本)
borowis

1

看起来,调整(降低)块大小可能会对压缩时间产生重大影响。

这是我在计算机上进行的实验的一些结果。我使用time命令来衡量执行时间。input.txt是一个约250mb的文本文件,包含任意json记录。

使用默认(最大)块大小(--best仅选择默认行为):

# time cat input.txt | bzip2 --best > input-compressed-best.txt.bz

real    0m48.918s
user    0m48.397s
sys     0m0.767s

使用最小的块大小(--fast参数):

# time cat input.txt | bzip2 --fast > input-compressed-fast.txt.bz

real    0m33.859s
user    0m33.571s
sys     0m0.741s

考虑到文档说明:这是一个令人惊讶的发现:

压缩和解压缩速度实际上不受块大小的影响


我目前最喜欢的是pbzip2。您也尝试过吗?这个问题是关于16个核心可用的环境。
guettli

不幸的是,@ guettli我必须坚持使用bzip。我将其用于Hadoop作业,而bzip是其中的内置压缩之一。因此,在某种程度上,它已经并行化。
雅各布·库库
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.