作为输入
当压缩文件作为MapReduce的输入时,MapReduce将自动通过扩展名找到相应的codec对其进行解压。
作为输出
当MapReduce的输出文件需要压缩时,可以更改mapred.output.compress为true,mapred.output.compression.codec为想要使用的codec的类名就可以了,当然你可以再代码中指定,通过调用FileOutputFormat的静态方法去设置这两个属性,我们来看代码:
public class MaxTemperatureWithCompression {
public static void main(String[] args) throws Exception {
if (args.length!=2){
System.out.println("Usage: MaxTemperature <input path> <out path>");
System.exit(-1);
}
Job job=new Job();
//以jar包的形式运行
job.setJarByClass(MaxTemperature.class);
job.setJobName("Max Temperature");
//添加输入路径
FileInputFormat.addInputPath(job, new Path(args[0]));
//设置输出路径
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//设置Mapper类
job.setMapperClass(MaxTemperatrueMapper.class);
//设置归约类
job.setCombinerClass(MaxTemperatureReducer.class);
//设置Reducer类
job.setReducerClass(MaxTemperatureReducer.class);
//设置输出key类型
job.setOutputKeyClass(Text.class);
//设置输出value类型
job.setOutputValueClass(IntWritable.class);
//设置reduce端输出进行压缩
FileOutputFormat.setCompressOutput(job, true);
//设置reducer端压缩的类型
FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
//0表示正常关闭JVM,1表示非正常关闭JVM
System.exit(job.waitForCompletion(true)?0:1);
}
}
输入也是一个压缩文件
~/hadoop/bin/hadoop com.sweetop.styhadoop.MaxTemperatureWithCompression input/data.gz output/
输出的每一个part都会被压缩,我们这里只有一个part,看下压缩了的输出
[hadoop@namenode test]$hadoop fs -get output/part-r-00000.gz .
[hadoop@namenode test]$ls
1901 1902 ch2 ch3 ch4 data.gz news.gz news.txt part-r-00000.gz
[hadoop@namenode test]$gunzip -c part-r-00000.gz
1901<span style="white-space:pre"> </span>317
1902<span style="white-space:pre"> </span>244
如果你要将序列化文件作为输出,你需要设置
mapred.output.compression.type属性来指定压缩类型,默认是RECORD,它会按单个record压缩,如果指定为BLOCK类型,它将一组record压缩,压缩效果自然是BLOCK好。
当然代码也可以设置,你只需要调用SequenceFileOutputFormat的setOutputCompressionType方法进行设置。
SequenceFileOutputFormat.setOutputCompressionType(job, SequenceFile.CompressionType.BLOCK);
如果你是用Tool接口来跑MapReduce的话,可以在命令行设置这些参数,明显比硬编码好很多。
压缩Map输出
即使你的MapReduce的输入输出文件都是未压缩的文件,你仍然可以对map任务的中间结果输出做压缩,因为它要写在硬盘并且通过网络传输到reduce节点,对其压缩可以提高很多性能,这些工作只要设置两个属性即可,我们来看下代码怎么设置:
Configuration conf = new Configuration();
conf.setBoolean("mapred.compress.map.output", true);
conf.setClass("mapred.map.output.compression.codec",GzipCodec.class, CompressionCodec.class);
Job job=new Job(conf);
注:我们可以将压缩的属性都设置在conf对象中,如下:
//对Map端输出进行压缩
conf.setBoolean("mapred.compress.map.output", true);
//设置map端输出使用的压缩类
conf.setClass("mapred.map.output.compression.codec", GzipCodec.class, CompressionCodec.class);
//对reduce端输出进行压缩
conf.setBoolean("mapred.output.compress", true);
//设置reduce端输出使用的压缩类
conf.setClass("mapred.output.compression.codec", GzipCodec.class, CompressionCodec.class);