hadoop streaming中的分区控制

339 阅读2分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」。

先前介绍了mapreduce框架对外开放的通用接口,也就是它的管道型操作。与我们直接的管道操作不同,它引入Hadoop计算框架的分布式计算机制用于实现并行机制。

实际上也就是比较常见的并行编程思想,通过把数据分成互相之间无关的分区(相关的数据自然就是属于同一个分区),然后各自进行运算。

mapreduce框架中,分区的数量与reducer的数量一致。 默认情况下,太大的值也会被进行hash映射实现分区,在Java的原生API中我们通过实现Partitioner类完成自定义分区。

hadoop streaming中就没这么好用了,在这里的话我们就需要做一个折中的操作了,hadoop streaming中提供了一个所谓的org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner可以根据我们指定的 决定分区的位置。

比如说:

1为给定值,则它会放置在1号reducer中。

它可以一种指定key值的类似方式来指定用于分区的值。再举个例子,当我们再做并行排序的时候,我们一般的设计是通过把待排序的值按区间做一个划分。比如1到100。每20划分为一个区间,这个可以用5个程序并行做快速排序。同理在更多的数据,更大的数据范围排序时也是一样的。这样我们期望的时间复杂度可以从O(nlogn)O(nlogn)下降到O(nlognm)O(\frac {nlogn}{m})。在一定程度上加速整体快速排序的速度。

如果我们是对1到100000的数据排序,使用50个reducer。那么mapper的输出可以像如下所示。

partition\tkey\n #其中partition为key整除2000,用于分区

然后在定义作业时,把key设为第二部分,分区设为第一部分。

-D mapreduce.job.reduces=50
-D stream.num.map.output.key.fields=2 # 1
-D mapreduce.partition.keypartitioner.options=-k1 #2
-D mapreduce.partition.keycomparator.options=-k2 #3
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner #4

1指定key占两个部分,2指定使用key中的1作为分区的值,而键由于额外添加了信息,为此key就要去掉分区部分重新排序,这里默认是按照字典序,有必要的情况可以想linux的sort命令一样指定排序规则。4则是指定排序方式。 至此我们就完成了Hadoop streaing中的自定义分区了。