2013-02-11 62 views
12

我们已经意识到,将GZip格式的文件归档为Hadoop处理并不是一个好主意。 Gzip已没有裂开的,以供参考,在这里是我不会重复的问题:Hadoop输入的最佳可拆分压缩= bz2?

我的问题是: BZip2是最好的归档压缩方式,它允许Hadoop并行处理单个归档文件? Gzip绝对不是,从我的阅读LZO有一些问题。

回答

15

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相当。

+4

这几天我更喜欢LZ4。 – 2015-02-25 18:55:51

+1

感到惊讶,你遗漏了Zlib。 – nikk 2016-10-25 21:06:58

2

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

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

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

您也可以在每个此类点上执行Z_SYNC_FLUSH后接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标记那样被搜索,尽管再次出现误报的可能性较小。

可以用串联的xz文件完成相同的操作,其头文件是七个字节:fd 37 7a 58 5a 00 00

+0

谢谢!如何准备gzip/bzip2文件并使它们可以通过入口点进行拆分? – Suman 2013-02-12 00:04:26

+0

查看更新的答案。 – 2013-02-12 02:42:21

+0

提示:因为我没有找到hadoop fs -bzcat,而是使用:hadoop fs -cat /FILENAME.bz | bzcat |少 – xgMz 2013-04-02 01:42:56

4

我不考虑对方的回答是正确的,bzip2的根据是:

http://comphadoop.weebly.com/

是裂开的。如果索引为,则LZO也是

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

要做到这一点,你可以写一个简单的MR作业来读取数据然后就再次写出来,然后需要确保您设置mapred.output.compression.codecorg.apache.hadoop.io.compress.BZip2Codec

+1

我会与这个答案,但它会好得多,如果你也会给我们如何:我如何创建索引bz2文件? – Gavriel 2014-04-23 09:11:57

+0

@Gavriel我不知道如何创建* indexed LZO *,但我会更新我的答案,以简要解释如何压缩到bzip2。 – samthebest 2014-04-23 12:05:15

+0

(嗯,我通过gzip压缩编写我的输出,因为这就是RedShift可以读取的内容),但是将任何正确的bzip2文件作为输入,还是需要传递一些特殊参数以获得块/索引? – Gavriel 2014-04-23 23:37:57