我想问一下Hadoop分区器,它是否在Mappers中实现?如何衡量使用默认散列分区程序的性能 - 是否有更好的分区程序来减少数据偏斜?
由于
答案 0 :(得分:4)
分区程序不在Mapper中。
以下是每个Mapper中发生的过程 -
以下是每个Reducer中发生的过程
现在每个Reducer收集来自每个mapper的所有文件,它会进入排序/合并阶段(已在mapper端完成排序),它将所有地图输出与维护排序顺序合并。
在reduce阶段,为排序后的输出中的每个键调用reduce函数。
下面是代码,说明了密钥分区的实际过程。 getpartition()将返回特定键必须根据其哈希码发送到的分区号/减少器。 Hashcode对于每个密钥都必须是唯一的,并且在整个环境中Hashcode应该是唯一的并且对于密钥是相同的。为此,hadoop为其密钥实现了自己的Hashcode,而不是使用java默认的哈希代码。
Partition keys by their hashCode().
public class HashPartitioner<K, V> extends Partitioner<K, V> {
public int getPartition(K key, V value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}
答案 1 :(得分:3)
分区程序是Mappers和Reducers之间的关键组件。它在Reducers之间分发地图发射的数据。
分区程序在每个Map Task JVM(java进程)中运行。
默认分区程序HashPartitioner
基于哈希函数工作,与TotalOrderPartitioner
之类的其他分区程序相比,速度更快。它在每个地图输出键上运行哈希函数,即:
Reduce_Number = (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
要检查Hash Partitioner的性能,请使用Reduce任务计数器,看看如何在reducers之间进行分发。
哈希分区程序是基本的分区程序,它不适合处理高偏度的数据。
为了解决数据偏差问题,我们需要编写从MapReduce API扩展Partitioner.java
类的自定义分区器类。
自定义分区程序的示例与RandomPartitioner
类似。这是在均衡器中均匀分布偏斜数据的最佳方法之一。