一、Partitioner介绍
Partitioner的作用是对Mapper产生的中间结果进行分片,以便将同一分组的数据交给同一个Reduce处理,它直接影响Reduce阶段的负载均衡(个人理解:就是按照Reduce的个数,将Mapper产生的中间结果按照关键字送给不同的Reduce,Reduce对相同关键字的数据进行处理)。
Partitioner在Map/Reduce中所处的位置,如下:
二、Partitioner的源代码解析
将相同关键字Key送到哪个Reduce上处理。
public abstract class Partitioner<KEY, VALUE> { /**
* Get the partition number for a given key (hence record) given the total
* number of partitions i.e. number of reduce-tasks for the job.
* 通过给定总的分区数(即一般为Reduce的个数),获得每个关键字Key所对应的分区(所对应的Reduce上)。
* <p>Typically a hash function on a all or a subset of the key.</p>
*
* @param key the key to be partioned. 关键字
* @param value the entry value.
* @param numPartitions the total number of partitions. 一般是Reduce的个数
* @return the partition number for the <code>key</code>. 哪个Reduce
*/
public abstract int getPartition(KEY key, VALUE value, int numPartitions); }
三、常用的Partitioner方法
1、HashPartitioner
HashPartitioner是MapReduce中Partitioner的默认实现。他是基于哈希值的分片方法。实现如下:
public class HashPartitioner<K, V> extends Partitioner<K, V> { /** Use {@link Object#hashCode()} to partition.
* key.hashCode()得到关键字Key的哈希值,numReduceTasks为Reduce的个数
* 这样可以将相同关键字Key的所有数据送给哪个Reduce
**/
public int getPartition(K key, V value, int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
} }
2、TotalOrderPartitioner
TotalOrderPartitioner是基于区间的分片方法,通常用在全排序中。