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);