Mapreduce三大组件之一Partitioner——实现自定义分区

MapReduce中数据流动
(1)最简单的过程: map - reduce
(2)定制了partitioner以将map的结果送往指定reducer的过程: map - partition - reduce
(3)增加了在本地先进性一次reduce(优化)过程: map - combin(本地reduce) - partition -reduce

1、概述:

Partitioner 组件可以让 Map 对 Key 进行分区,从而将不同分区的 Key 交由不同的 Reduce 处理。简洁明了

2、Partitioner的作用

分区Partitioner主要作用在于以下两点

(1)根据业务需要,产生多个输出文件;

(2)多个reduce任务并发运行,提高整体job的运行效率

3、代码实现步骤

	1、自定义 TelephonePartitioner 类,继承抽象类 Partitioner
	2、创建 HashMap 并添加相应值,key为手机号前三位数字,value为对应分区号
	3、重写getPartition 方法,对 Map 输出的 key 实现自定义分区
	4、通过 job.setPartitionerClass( ) 来设置自定义的 Partitioner 类
	5、通过job.setNumReduceTasks( )来设置 Reduce 的数量最好是有几个分区就设置几个 Reduce

4、代码实例

import java.util.HashMap;
import java.util.Map;

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Partitioner;

/*
####  * 实现自定义分区
 * KEY, VALUE对应Map端的输出数据的key-value类型
 */
public class TelephonePartitioner extends Partitioner<FlowBeanSort, NullWritable>{
	/*
	 * 134---->0
	 * 135---->1
	 * 136---->2
	 * 137---->3
	 * 138---->4
	 * 139---->5
	 * 其他的手机号放到---->6
	 
	 * (non-Javadoc)
	 * @see org.apache.hadoop.mapreduce.Partitioner#getPartition(java.lang.Object, java.lang.Object, int)
	 */
	private static Map<String, Integer> teleMap=new HashMap<>();
	static{
		teleMap.put("134", 0);
		teleMap.put("135", 1);
		teleMap.put("136", 2);
		teleMap.put("137", 3);
		teleMap.put("138", 4);
		teleMap.put("139", 5);
	}
#### 	//重写自定义分区方法
	@Override
	public int getPartition(FlowBeanSort key, NullWritable value, int numPartitions) {
		//获取手机号
		String tele=key.getTelephone();
		//截取手机号前3位(前闭后开)
		String prefixThree=tele.substring(0, 3);
		//判断map中是否包含手机号的前3位
		if(teleMap.containsKey(prefixThree)){
			//获取对应分区号
			int number=teleMap.get(prefixThree);
			return number;
		}else{
			return 6;
		}
	}

客户端调用

job.setPartitionerClass(TelephonePartitioner.class);
//设置reducetask的个数(不设置默认是一个)将原有数据分成7个来存放
job.setNumReduceTasks(7);
!个人笔记,不喜勿喷

你可能感兴趣的:(Hadoop)