MapReduce学习整理(3)——压缩篇

1 压缩格式

运算密集型的job,少用压缩,IO密集型的job,多用压缩。

压缩格式hadoop自带算法文件拓展名是否可以切分换成压缩格式后,原
来的程序是否需要修改
DEFAULT是,直接使用DEFAULT.deflate和文本处理一样,不需要修改
Gzip是,直接使用DEFAULT.gz和文本处理一样,不需要修改
bzip2是,直接使用bzip2.bz2和文本处理一样,不需要修改
LZO否,需要安装LZO.lzo需要建立索引,还需要指定输入格式
Snappy否,需要安装Snappy.snappy和文本处理一样,不需要修改

为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器,如下表所示

压缩格式对应的编码/解码器
DEFLATEorg.apache.hadoop.io.compress.DefaultCodec
gziporg.apache.hadoop.io.compress.GzipCodec
bzip2org.apache.hadoop.io.compress.BZip2Codec
LZOcom.hadoop.compression.lzo.LzopCodec
Snappyorg.apache.hadoop.io.compress.SnappyCodec

2 压缩方式

压缩格式压缩率压缩速度是否支持split应用场景
Gzip比较高比较快当每个文件压缩之后在130M以内的(1个块大小内),
都可以考虑用gzip
Bzip2很高对速度要求不高,但需要较高的压缩率的时候,可以作为
MR作业的输出格式;
输出之后的数据比较大,处理之后的数据需要压缩存档减少
磁盘空间并且以后数据用得比较少的情况;
对单个很大的文本文件想压缩减少存储空间,同时又需要支持
split,而且兼容之前的应用程序(即应用程序不需要修改)。
Lzo比gzip低hadoop中较为流行的压缩方式
Snappy作为Map到Reduce的中间数据的压缩格式;
作为一个MR作业的输出和另外一个MR作业的输入。

注:通常来讲,压缩率和压缩速度成反比,压缩速率高势必会导致压缩速度变慢。反之亦然。

3 压缩位置

压缩可以在mapreduce的所有过程使用。
压缩可以在 MapReduce 作用的任意阶段启用。

4 压缩参数配置

参数默认值阶段使用建议
io.compression.codecs
(在 core-site.xml 中配置)
org.apache.hadoop.io.compress.DefaultCodec
org.apache.hadoop.io.compress.GzipCodec
org.apache.hadoop.io.compress.BZip2Codec
输入压缩Hadoop 使用文件扩展名判断是否支持某种编解码器
mapreduce.map.output.compress
在 mapred-site.xml中配置)
falsemapper 输出这个参数设为true 启用压缩
mapreduce.map.output.compress.codec
( 在mapred-site.xml 中配置)
org.apache.hadoop.io.compress.DefaultCodecmapper 输出使 用LZO 或snappy编解码器在此阶段压缩数据
mapreduce.output.fileoutputformat.compress
( 在mapred-site.xml 中配置)
falsereducer 输出这个参数设为true 启用压缩
mapreduce.output.fileoutputformat.compress.codec
(在mapred-site.xml 中配置)
org.apache.hadoop.io.compress.DefaultCodecreducer 输出使用标准工具或者编解 码器,如gzip 和bzip2
mapreduce.output.fileoutputformat.compress.type
(在mapred-site.xml 中配置)
RECORDreducer 输出SequenceFile输出使用的压缩 类型 :NONE和BLOCK

5 代码实例

5.1 解压缩操作

public class TestCompress {
	public static void main(String[] args) throws Exception {
		//1.测试压缩
		//compress("e:/hello.txt","org.apache.hadoop.io.compress.BZip2Codec");
		//compress("e:/hello.txt","org.apache.hadoop.io.compress.GzipCodec");
		compress("e:/hello.txt","org.apache.hadoop.io.compress.DefaultCodec");
		//2.测试解压
		decompress("e:/hello.txt.deflate");
	}

	//测试压缩
	private static void compress(String filename, String method) throws Exception {
		// 1.获取输入流
		  //将文件转化为输入流
		FileInputStream fis=new FileInputStream(new File(filename));
		  //获取压缩的格式
		Class classname=Class.forName(method);
		  //设置压缩编解码
		CompressionCodec codec=(CompressionCodec)ReflectionUtils.newInstance(classname, new Configuration());		
		// 2.获取输出流
		  //创建输出流
		FileOutputStream fos=new FileOutputStream(new File(filename+codec.getDefaultExtension()));
		  //创建压缩后的输出流
		CompressionOutputStream cos=codec.createOutputStream(fos);
		// 3.流的对转
		IOUtils.copyBytes(fis, cos, 1024*1024*5, false);
		// 4.关闭资源
		fis.close();
		cos.close();
		fos.close();
		}
	//测试解压
	private static void decompress(String filename) throws Exception, IOException{
		// 0.校验能不能解压
		CompressionCodecFactory factory=new CompressionCodecFactory(new Configuration());
		CompressionCodec codec=factory.getCodec(new Path(filename));
		if(codec==null){
			System.out.println("不支持该解码器"+filename);
			return;
		}
		// 1.获取输入流
		CompressionInputStream cis=codec.createInputStream(new FileInputStream(new File(filename)));
		// 2.获取输出流
		FileOutputStream fos=new FileOutputStream(new File(filename+"111"));
		// 3.流的对转
		IOUtils.copyBytes(cis, fos, 1024*1024*5, false);
		// 4.关闭资源
		cis.close();
		fos.close();
	}
}

5.2 以WordCount案例为例。

public class WordcountDriver {
	public static void main(String[] args) throws Exception {
		
		args=new String[]{"e:/input/inputword","e:/output/outputword2"};
		
		//1.获取配置信息,job对象实例
		Configuration configuration= new Configuration();
		
		//开启map端输出压缩
		configuration.setBoolean("mapreduce.map.output.compress",true);
		//设置map端输出压缩方式
		configuration.setClass("mapreduce.map.output.compress.codec",BZip2Codec.class,CompressionCodec.class);
		
		Job job=Job.getInstance(configuration);
		 
		//2指定本程序的jar包所在的本地路径
		//job.setJar("");
		job.setJarByClass(WordcountDriver.class);
		
		//3 指定本业务job要使用的自定义的mapper/Reducer业务类
		job.setMapperClass(WordcountMapper.class);
		job.setReducerClass(WordcountReducer.class);
		
		
		//4指定mapper输出数据可kv类型
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		//5设置最终输出数据类型
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
		
		//6设置数据输入和输出文件的路径
		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));
		
		//设置reduce端输出压缩开启
		FileOutputFormat.setCompressOutput(job,true);
		//设置压缩的方式
		//FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);
		//FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
		FileOutputFormat.setOutputCompressorClass(job, DefaultCodec.class);
		
		//7提交代码
		//job.submit();
		boolean result=job.waitForCompletion(true);
		System.exit(result ? 0:1);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值