我们已经意识到将GZip格式的文件归档用于Hadoop处理并不是一个好主意。 GZip不可分割,作为参考,以下是我不会重复的问题:
我的问题是:BZip2是最好的归档压缩,它允许Hadoop并行处理单个归档文件吗? Gzip肯定不是,从我的阅读LZO有一些问题。
答案 0 :(得分:20)
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相媲美。
答案 1 :(得分:6)
我不认为其他答案是正确的,bzip2根据这个:
是可拆分的。如果索引,LZO也是。
所以答案是肯定的,如果你想使用比你有文件更多的映射器,那么你将需要使用bzip2。
为此,您可以编写一个简单的MR作业来读取数据,然后再将其写出来,然后需要确保将mapred.output.compression.codec
设置为org.apache.hadoop.io.compress.BZip2Codec
答案 2 :(得分:2)
以下是gzip的五种方法,三种需要索引,两种不需要。
可以为zran.c创建任何gzip文件的索引,即不是特殊构造的索引。然后,您可以在块边界处开始解压缩。索引包括每个入口点的32K未压缩数据历史记录。
如果您正在构建gzip文件,那么可以使用其索引在这些入口点处不需要未压缩历史记录的周期性入口点,从而形成较小的索引。这是通过zlib中Z_FULL_FLUSH
的{{1}}选项完成的。
您还可以在每个此类点执行deflate()
后跟Z_SYNC_FLUSH
,这会插入两个标记。然后,您可以搜索九字节模式Z_FULL_FLUSH
来查找它们。这与在bzip2文件中搜索六字节标记没有什么不同,除了九个字节的误报率要小得多。那么您不需要单独的索引文件。
gzip和xz都支持简单连接。这使您可以以另一种方式轻松地为并行解压缩准备存档。简而言之:
00 00 ff ff 00 00 00 ff ff
将导致比较成功。
然后,您可以简单地压缩所需大小的块并连接结果。将索引保存到每个gzip流的开头的偏移量。从那些补偿中解压缩。您可以根据自己的应用选择自己喜欢的块大小。但是,如果它们太小,压缩就会受到影响。
通过简单连接gzip文件,如果您将每个块都设置为固定的未压缩大小,也可以放弃索引。然后每个块以相同的四个字节结束,未压缩的长度以小端顺序结束,例如,对于1个MiB块,gzip < a > a.gz
gzip < b > b.gz
cat a.gz b.gz > c.gz
gunzip < c.gz > c
cat a b | cmp - c
,然后是来自下一个块的00 00 10 00
,这是gzip头的开始。然后可以像bzip2标记一样搜索这个七字节标记,尽管再次使用较小的误报概率。
对于连接的xz文件也可以这样做,其标头是七个字节:1f 8b 08
。
答案 3 :(得分:0)
我的2cents,bzip写起来很慢。经过Apache Spark 1.6.2和Hadoop 2.7的测试,压缩了50Go的简单JSON文件,使用bzip的时间比使用gzip的时间长2倍。
但是使用bzip,50Go ==> 4 Go!