我想问一下hadoop分区器,它是在mappers中实现的吗?。如何衡量使用默认哈希分区器的性能-是否有更好的分区器来减少数据倾斜?谢谢
qcuzuvrc1#
分区器是Map器和还原器之间的关键组件。它在减速器之间分配Map发射数据。partitioner在每个map任务jvm(java进程)中运行。默认分区器 HashPartitioner 基于哈希函数工作,与其他类似的分区器相比速度非常快 TotalOrderPartitioner . 它在每个Map输出键上运行哈希函数,即:
HashPartitioner
TotalOrderPartitioner
Reduce_Number = (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
要检查hash partitioner的性能,请使用reduce任务计数器并查看reducer之间的分布情况。hash分区器是一种基本的分区器,不适合处理高偏态数据。为了解决数据倾斜问题,我们需要编写自定义的partitioner类 Partitioner.java 从mapreduce api初始化。自定义分区器的示例如下 RandomPartitioner . 它是在减速器之间均匀分布倾斜数据的最佳方法之一。
Partitioner.java
RandomPartitioner
nkhmeac62#
分区器不在Map器中。下面是每个Map器中发生的过程-每个Map任务都将其输出写入循环缓冲区内存(而不是磁盘)。当缓冲区达到阈值时,后台线程开始将内容溢出到磁盘[缓冲区大小由mapreduce.task.io.sort.mb属性控制,默认值为100 mb,溢出由mapreduce.io.sort.spill.percent属性控制,默认值为0.08或80%]。在溢出到磁盘之前,数据将被分区,并对应于还原器,它们将被发送到内存中,并在每个分区中按键进行排序在每种排序的结果上运行合并器函数(允许更少的数据写入和传输,这需要特别完成)压缩(可选)[mapred.compress.map.output=true;mapred.map.output.compression.codec=codeName]对磁盘的写入和输出文件的分区可通过http供还原程序使用。下面是每个减速器中发生的过程现在每个reducer从每个mapper收集所有文件,它进入排序/合并阶段(排序已经在mapper端完成),该阶段合并所有map输出并保持排序顺序。在reduce阶段,为排序输出中的每个键调用reduce函数。下面是代码,说明了密钥分区的实际过程。getpartition()将根据哈希代码返回特定键必须发送到的分区号/大小写。hashcode对于每个键都必须是唯一的,并且在整个环境中,hashcode对于一个键应该是唯一的和相同的。为此,hadoop为其密钥实现了自己的hashcode,而不是使用java默认的hashcode。
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; } }
2条答案
按热度按时间qcuzuvrc1#
分区器是Map器和还原器之间的关键组件。它在减速器之间分配Map发射数据。
partitioner在每个map任务jvm(java进程)中运行。
默认分区器
HashPartitioner
基于哈希函数工作,与其他类似的分区器相比速度非常快TotalOrderPartitioner
. 它在每个Map输出键上运行哈希函数,即:要检查hash partitioner的性能,请使用reduce任务计数器并查看reducer之间的分布情况。
hash分区器是一种基本的分区器,不适合处理高偏态数据。
为了解决数据倾斜问题,我们需要编写自定义的partitioner类
Partitioner.java
从mapreduce api初始化。自定义分区器的示例如下
RandomPartitioner
. 它是在减速器之间均匀分布倾斜数据的最佳方法之一。nkhmeac62#
分区器不在Map器中。
下面是每个Map器中发生的过程-
每个Map任务都将其输出写入循环缓冲区内存(而不是磁盘)。当缓冲区达到阈值时,后台线程开始将内容溢出到磁盘[缓冲区大小由mapreduce.task.io.sort.mb属性控制,默认值为100 mb,溢出由mapreduce.io.sort.spill.percent属性控制,默认值为0.08或80%]。在溢出到磁盘之前,数据将被分区,并对应于还原器,它们将被发送到内存中,并在每个分区中按键进行排序
在每种排序的结果上运行合并器函数(允许更少的数据写入和传输,这需要特别完成)
压缩(可选)[mapred.compress.map.output=true;mapred.map.output.compression.codec=codeName]
对磁盘的写入和输出文件的分区可通过http供还原程序使用。
下面是每个减速器中发生的过程
现在每个reducer从每个mapper收集所有文件,它进入排序/合并阶段(排序已经在mapper端完成),该阶段合并所有map输出并保持排序顺序。
在reduce阶段,为排序输出中的每个键调用reduce函数。
下面是代码,说明了密钥分区的实际过程。getpartition()将根据哈希代码返回特定键必须发送到的分区号/大小写。hashcode对于每个键都必须是唯一的,并且在整个环境中,hashcode对于一个键应该是唯一的和相同的。为此,hadoop为其密钥实现了自己的hashcode,而不是使用java默认的hashcode。