Hadoop中的压缩(2) Mapper中使用压缩

1 输入文件

若输入文件时压缩过的,那么被MR读取时它们会被自动解压。根据文件扩展名可以确定使用哪一个文件解码器。TextInputFormat的getRecordReader方法,再进入LineRecordReader。

 if (isCompressedInput()) {
      decompressor = CodecPool.getDecompressor(codec);
      if (codec instanceof SplittableCompressionCodec) {
        final SplitCompressionInputStream cIn =
          ((SplittableCompressionCodec)codec).createInputStream(
            fileIn, decompressor, start, end,
            SplittableCompressionCodec.READ_MODE.BYBLOCK);
        in = new CompressedSplitLineReader(cIn, job, recordDelimiter);
        start = cIn.getAdjustedStart();
        end = cIn.getAdjustedEnd();
        filePosition = cIn; // take pos from compressed stream
      } else {
        in = new SplitLineReader(codec.createInputStream(fileIn,
            decompressor), job, recordDelimiter);
        filePosition = fileIn;
      }
    } else {
      fileIn.seek(start);
      in = new SplitLineReader(fileIn, job, recordDelimiter);
      filePosition = fileIn;
}

2 输出文件

若要对输出的结果进行压缩,需要设置两个值:
mapred.output.compress=true
mapred.output.compression.codec=编码/解码器名

jobConf.setBoolean("mapred.output.compress",true);
jobCon.setClass("mapred.output.compression.codec", GzipCodec.class,CompressionCodc.class);
若要将序列文件做为输出,需要设置mapred.output.compression.type属性来指定压缩类型,默认是RECORD类型,它会按单个的record压缩,若指定为BLOCK类型,它将一组record压缩,压缩效果自然是BLOCK好。当然代码里也可以设置,调用SequenceFileOutputFormat的setOutputCompressionType方法进行设置。
SequenceFileOutputFormat.setOutputCompressionType(job, SequenceFile.CompressionType.BLOCK); 


3 中间文件

即使MR使用非压缩的输入和输出,我们也会受益于压缩的中间结果。因为map作业的输出会被写入磁盘,并通过网络传输到reducer节点。

Configuration conf = new Configuration();
conf.setBoolean("mapred.compress.map.output", true);
conf.setClass("mapred.map.output.compression.codec",GzipCodec.class, 
CompressionCodec.class);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章