MapReduce应用

MapReduce应用

一. mapreduce中的combiner

  1. combiner是MR程序中Mapper和Reducer之外的一种组件
  2. combiner组件的父类就是Reducer
  3. combiner和reducer的区别在于运行的位置:
    Combiner是一个本地化的reduce操作,它是map运算的后续操作,主要是在map计算出中间文件前做一个简单的合并重复key值的操作;每一个map都可能会产生大量的本地输出,Combiner的作用就是对map端的输出先做一次合并,以减少在map和reduce节点之间的数据传输量,以提高网络IO性能.
  4. combiner的意义就是对每一个maptask的输出进行局部汇总,以减小网络传输量
    具体实现步骤:
    1、自定义一个combiner继承Reducer,重写reduce方法
    2、在job中设置: job.setCombinerClass(CustomCombiner.class)

二. MAPREDUCE中的序列化 与 自定义排序

  1. 概述
    Java的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,header,继承体系),不便于在网络中高效传输;所以,hadoop自己开发了一套序列化机制(Writable),精简,高效

  2. 自定义对象实现MR中的序列化接口
    如果需要将自定义的bean放在key中传输,则还需要实现comparable接口,因为mapreduce框中的shuffle过程一定会对key进行排序,此时,自定义的bean实现的接口应该是Writable接口,实现序列化方法public void readFields(DataInput in)与反序列化public void write(DataOutput out)

//需求,当我们根据一段日志进行排序时,我们可以使用shuffle阶段的排序给我们自动排序,但是实体必须要三个条件:

A. 实体序列化
B. 自定义排序规则
C. 实体作为mapper阶段的key

	public class FlowBean implements WritableComparable<FlowBean>{

	long upflow;
	long downflow;
	long sumflow;
	
	//如果空参构造函数被覆盖,一定要显示定义一下,否则在反序列时会抛异常
	public FlowBean(){}
	
	public FlowBean(long upflow, long downflow) {
		super();
		this.upflow = upflow;
		this.downflow = downflow;
		this.sumflow = upflow + downflow;
	}
	
	public long getSumflow() {
		return sumflow;
	}

	public void setSumflow(long sumflow) {
		this.sumflow = sumflow;
	}

	public long getUpflow() {
		return upflow;
	}
	public void setUpflow(long upflow) {
		this.upflow = upflow;
	}
	public long getDownflow() {
		return downflow;
	}
	public void setDownflow(long downflow) {
		this.downflow = downflow;
	}

	//序列化,将对象的字段信息写入输出流
	@Override
	public void write(DataOutput out) throws IOException {
		out.writeLong(upflow);
		out.writeLong(downflow);
		out.writeLong(sumflow);
		
	}

	//反序列化,从输入流中读取各个字段信息
	@Override
	public void readFields(DataInput in) throws IOException {
		upflow = in.readLong();
		downflow = in.readLong();
		sumflow = in.readLong();
		
	}
	
	@Override
	public String toString() {
		return upflow + "\t" + downflow + "\t" + sumflow;
	}
	@Override
	public int compareTo(FlowBean o) {
		//自定义倒序比较规则
		return sumflow > o.getSumflow() ? -1:1;
	}
	}

三. 自定义分区 Partitioner

  1. 概述
    Mapreduce中会将map输出的kv对,按照相同key分组,然后分发给不同的reducetask
    默认的分发规则为:根据key的hashcode%reducetask数来分发

  2. 自定义分区规则
    自定义一个CustomPartitioner继承抽象类:Partitioner,然后在job对象中,设置自定义partitioner: job.setPartitionerClass(CustomPartitioner.class)

     public class ProvincePartitioner extends Partitioner<Text, FlowBean> {
     
     	static HashMap<String, Integer> provinceMap = new HashMap<String, Integer>();
     
     	static {
     
     		provinceMap.put("135", 0);
     		provinceMap.put("136", 1);
     		provinceMap.put("137", 2);
     		provinceMap.put("138", 3);
     		provinceMap.put("139", 4);
     
     	}
     
     	@Override
     	public int getPartition(Text key, FlowBean value, int numPartitions) {
     
     		Integer code = provinceMap.get(key.toString().substring(0, 3));
     
     		return code == null ? 5 : code;
     	}
     
     }
    

四. 压缩

  1. 概述
    mapreduce的一种优化策略:通过压缩编码对mapper或者reducer的输出进行压缩,以减少磁盘IO,提高MR程序运行速度(但相应增加了cpu运算负担)

  2. 使用
    (1)、Mapreduce支持将map输出的结果或者reduce输出的结果进行压缩,以减少网络IO或最终输出数据的体积
    (2)、压缩特性运用得当能提高性能,但运用不当也可能降低性能
    (3)、基本原则:
    运算密集型的job,少用压缩
    IO密集型的job,多用压缩

  3. Mapper输出压缩

    在配置参数或在代码中都可以设置reduce的输出压缩
    (1)、在配置参数中设置
    mapreduce.map.output.compress=false
    mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.DefaultCodec

    (2)、在代码中设置:
    conf.setBoolean(Job.MAP_OUTPUT_COMPRESS, true);
    conf.setClass(Job.MAP_OUTPUT_COMPRESS_CODEC, GzipCodec.class, CompressionCodec.class);

  4. Reducer输出压缩

    在配置参数或在代码中都可以设置reduce的输出压缩
    (1)、在配置参数中设置
    mapreduce.output.fileoutputformat.compress=false
    mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.DefaultCodec
    mapreduce.output.fileoutputformat.compress.type=RECORD

    (2)、在代码中设置
    Job job = Job.getInstance(conf);
    FileOutputFormat.setCompressOutput(job, true);
    FileOutputFormat.setOutputCompressorClass(job, (Class<? extends ) Class.forName(""));

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值