Hadoop分区器

时间:2014-12-22 00:14:44

标签: hadoop mapreduce partitioner

我想问一下Hadoop分区器,它是否在Mappers中实现?如何衡量使用默认散列分区程序的性能 - 是否有更好的分区程序来减少数据偏斜?

由于

2 个答案:

答案 0 :(得分:4)

分区程序不在Mapper中。

以下是每个Mapper中发生的过程 -

  • 每个map任务都将其输出写入循环缓冲区内存(而不是磁盘)。 当缓冲区达到阈值时,后台线程开始将内容溢出到磁盘。 [缓冲区大小由mapreduce.task.io.sort.mb属性& amp;默认为100 MB,溢出由mapreduce.io.sort.spill.percent属性和&amp ;;默认为0.08或80%]。在溢出到磁盘之前 数据是分区对应于它们将被发送到的reducer 在每个分区中按键执行内存中排序
  • 对每种类型的结果运行组合器功能(减少数据写入和传输,这需要专门完成)
  • 压缩(可选)[mapred.compress.map.output = true; mapred.map.output.compression.codec = CodecName]
  • 写入磁盘,输出文件的分区可通过HTTP进行缩减。

以下是每个Reducer中发生的过程

  • 现在每个Reducer收集来自每个mapper的所有文件,它会进入排序/合并阶段(已在mapper端完成排序),它将所有地图输出与维护排序顺序合并。

  • 在reduce阶段,为排序后的输出中的每个键调用reduce函数。

enter image description here

下面是代码,说明了密钥分区的实际过程。 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类似。这是在均衡器中均匀分布偏斜数据的最佳方法之一。