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