Hadoop 如何压缩 Mapper 输出但不压缩 Reducer 输出?

26
我有一个map-reduce的Java程序,尝试只对mapper输出进行压缩而不是reducer输出。我认为可以通过在Configuration实例中设置以下属性来实现。但是,当我运行作业时,reducer生成的输出仍然被压缩,因为生成的文件是:part-r-00000.gz。有人成功地只压缩了mapper数据而不是reducer吗?这真的可能吗?
//压缩mapper输出
conf.setBoolean("mapred.output.compress", true);
conf.set("mapred.output.compression.type", CompressionType.BLOCK.toString());
conf.setClass("mapred.output.compression.codec", GzipCodec.class, CompressionCodec.class);
5个回答

55

mapred.compress.map.output: 是指在Mapper和Reducer之间对数据进行压缩。如果使用Snappy编解码器,这很可能会增加读写速度并减少网络开销。不要在这里分心。这些文件不会存储在HDFS中。它们是仅存在于MapReduce作业期间的临时文件。

mapred.map.output.compression.codec: 我建议使用Snappy。

mapred.output.compress: 这个布尔标志将定义整个MapReduce作业是否输出压缩数据。我总是将其设置为true。更快的读写速度和减少磁盘空间的使用。

mapred.output.compression.type: 我使用块压缩格式。这将使所有压缩格式(gzip、snappy和bzip2)都可以进行分割,只需确保使用可分割的文件格式,如Sequence、RCFile或Avro。

mapred.output.compression.codec: 这是MapReduce作业的压缩编解码器。我主要使用以下三种:Snappy(最快的读写速度,2x-3x的压缩比),gzip(正常的读取速度,较快的写入速度,5x-8x的压缩比),bzip2(较慢的读写速度,8x-12x的压缩比)。

还要记住,当压缩MapReduce输出时,由于分割的原因,压缩将根据您的排序顺序而不同。相似的数据越靠在一起,压缩效果越好。


5
如何知道地图输出是否已经压缩?通过比较未压缩和已压缩的“Map output bytes”来确定吗?我看到我的地图输出字节数约为91 GB。它适合进行地图输出压缩吗?通常,我该如何找到适合进行地图输出压缩的文件?“map output bytes”是一个好的指标吗? - Venk K
1
Hadoop 2.* 版本现在使用 MapReduce.*.*。请阅读下面我的答案。 - fengyun
请问您能详细说明“这将使所有压缩格式的压缩可分割”吗?根据我的经验,gz 格式并不是真正可分割的。文件会存储在多个块中,但当映射器读取它们时,每个文件只会生成一个映射器。这意味着除第一个块外的所有块都需要通过网络获取。 - markob

21

如果有人对如何让avro工作感兴趣,由于avro仅支持snappy和deflate,因此此配置是最佳选择。最终减小的文件名不会改变,但是由于内部块级别的压缩,您会发现文件大小发生了变化。更多详情请见:http://www.quora.com/Can-avro-data-files-be-lzop-compressed-in-Hadoop - Ravindranath Akila
在向 EMR 添加步骤时,您是否设置了这些设置? - Barbaros Alp

13

"输出压缩"将压缩您的最终输出。如果要仅压缩地图输出,请使用类似以下内容的代码:

  conf.set("mapred.compress.map.output", "true")
  conf.set("mapred.output.compression.type", "BLOCK"); 
  conf.set("mapred.map.output.compression.codec", "org.apache.hadoop.io.compress.GzipCodec"); 

1
使用gzip作为压缩器并不是一个好主意。主要问题在于它无法分割。 - Niels Basjes
6
为什么?我以为 Mapper 输出不会被分割,只有使用 Reducer 或 Identity Reducer 才可能导致输出被分割。 - Marcin
我的理解是使用GZIP压缩输入数据不是一个好主意。原因是它不可分割。但是在Map输出中使用gzip没有问题。 - root1982
Gzip比其他算法(如LZO和Snappy)稍微慢一些,但使用Gzip可以获得更好的压缩效果。值得一提的是,AWS的EMR默认使用Snappy。 - Dolan Antenucci
现在这些已经过时了,请使用 mapreduce.map.output.compressmapreduce.output.fileoutputformat.compress.typemapreduce.map.output.compress.codec - rsedlr

2
  1. 您需要将"mapred.compress.map.output"设置为true。
  2. 可选地,您可以通过设置"mapred.map.output.compression.codec"来选择压缩编解码器。 注意1:mapred输出压缩永远不应该是BLOCK。有关详细信息,请参见以下JIRA: https://issues.apache.org/jira/browse/HADOOP-1194 注意2:GZIP和BZ2会占用大量CPU资源。如果您的网络速度较慢,而GZIP或BZ2提供更好的压缩比,则可能值得花费CPU周期。否则,请考虑使用LZO或Snappy编解码器。
    注意3:如果您想使用map输出压缩,请考虑安装本地编解码器,该编解码器通过JNI调用并提供更好的性能。

另外,我们能否只压缩映射器的值而不是键? - Piyush Kansal

1
如果您使用MapR的Hadoop分发,您可以在不涉及编解码器的情况下获得压缩的好处。MapR在文件系统级别本地压缩,因此应用程序无需了解或关心。可以在目录级别上打开或关闭压缩,因此您可以压缩输入但不压缩输出或其他任何内容。通常,压缩非常快速(默认使用类似于snappy的算法),大多数应用程序在使用本地压缩时会看到性能提升。如果您的文件已经压缩,那么会很快检测到并自动关闭压缩,因此您也不会受到惩罚。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接