27

我们意识到为 Hadoop 处理以 GZip 格式归档文件并不是一个好主意,这有点太晚了。GZip 不可拆分,作为参考,以下是我不会重复的问题:

我的问题是:BZip2 是允许 Hadoop 并行处理单个存档文件的最佳存档压缩吗?Gzip 肯定不行,而且从我的阅读来看 LZO 有一些问题。

4

4 回答 4

29

BZIP2在 hadoop 中是可拆分的——它提供了非常好的压缩比,但从 CPU 时间和性能来看并没有提供最佳结果,因为压缩非常消耗 CPU。

LZO在 hadoop 中是可拆分的——利用hadoop-lzo你有可拆分的压缩 LZO 文件。您需要有外部 .lzo.index 文件才能并行处理。该库提供了以本地或分布式方式生成这些索引的所有方法。

LZ4在 hadoop 中是可拆分的——利用hadoop-4mc你有可拆分的压缩 4mc 文件。您不需要任何外部索引,您可以使用提供的命令行工具或通过 Java/C 代码在 hadoop 内部/外部生成档案。4mc 可以在任何级别的速度/压缩比下在 hadoop LZ4 上使用:从达到 500 MB/s 压缩速度的快速模式到提供更高压缩比的高/超模式,几乎可以与 GZIP 相媲美。

于 2014-09-17T10:43:35.067 回答
6

这里有五种使用 gzip 的方法,三种需要索引,两种不需要。

可以为任何 gzip 文件创建索引,即不是专门构造的,如zran.c所做的那样。然后您可以在块边界处开始解压缩。该索引包括每个入口点的 32K 未压缩数据历史记录。

如果您正在构建 gzip 文件,则可以使用周期性入口点来制作它,其索引不需要在这些入口点处未压缩的历史记录,从而使索引更小。这是通过zlib 中的Z_FULL_FLUSH选项来完成的。deflate()

您还可以在每个此类点执行 aZ_SYNC_FLUSH后跟 a ,这将插入两个标记。Z_FULL_FLUSH然后你可以搜索九字节模式00 00 ff ff 00 00 00 ff ff来找到那些。这与在 bzip2 文件中搜索 6 字节标记没有什么不同,除了 9 字节时误报的可能性要小得多。那么你就不需要单独的索引文件了。

gzip 和 xz 都支持简单的连接。这使您可以轻松地以另一种方式为并行解压缩准备存档。简而言之:

gzip < a > a.gz
gzip < b > b.gz
cat a.gz b.gz > c.gz
gunzip < c.gz > c
cat a b | cmp - c

将导致比较成功。

然后,您可以简单地压缩成所需大小的块并连接结果。将索引保存到每个 gzip 流开始的偏移量。从这些偏移中解压缩。您可以根据自己的应用选择块的大小。但是,如果将它们设置得太小,则会影响压缩。

通过 gzip 文件的简单连接,如果您将每个块设置为固定的未压缩大小,您也可以放弃索引。然后每个块以相同的四个字节结束,未压缩的长度以小端顺序排列,例如00 00 10 00对于 1 MiB 块,然后是1f 8b 08下一个块,它是 gzip 标头的开始。然后可以像 bzip2 标记一样搜索该 7 字节标记,但误报的可能性更小。

可以对连接的 xz 文件执行相同的操作,其标头是七个字节:fd 37 7a 58 5a 00 00.

于 2013-02-11T23:54:51.273 回答
6

我不认为另一个答案是正确的,bzip2 根据这个:

http://comphadoop.weebly.com/

是可拆分的。如果索引LZO 也是如此。

所以答案是肯定的,如果你想使用比文件更多的映射器,那么你会想使用 bzip2。

为此,您可以编写一个简单的 MR 作业来读取数据,然后再次将其写出,然后您需要确保设置mapred.output.compression.codecorg.apache.hadoop.io.compress.BZip2Codec

于 2014-04-14T17:10:21.370 回答
1

我的 2cents,bzip 写起来很慢。用 Apache Spark 1.6.2、Hadoop 2.7 测试,压缩一个简单的 50Go 的 JSON 文件,bzip 比 gzip 需要 2 倍的时间。

但是使用 bzip,50Go ==> 4 Go!

于 2018-09-07T10:13:35.437 回答