「这是我参与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个程序并行做快速排序。同理在更多的数据,更大的数据范围排序时也是一样的。这样我们期望的时间复杂度可以从下降到。在一定程度上加速整体快速排序的速度。
如果我们是对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中的自定义分区了。