现在的位置: 首页 > 综合 > 正文

Hadoop MapReduce中的压缩

2018年06月05日 ⁄ 综合 ⁄ 共 2559字 ⁄ 字号 评论关闭

作为输入

当压缩文件作为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);

【上篇】
【下篇】

抱歉!评论已关闭.