程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

大数据之-Hadoop3.x_MapReduce_HashPartitioner分区

balukai 2025-05-10 19:55:17 文章精选 2 ℃



我们通过一个案例来说明,比如我们要将135开头的手机号,放到一个文件中,将136开头的手机号,


放到另一个文件中..这个需求怎么来做.



1.首先我们来看一下hadoop的默认的分区是怎么做的,可以看到,默认进行分区的,一个类,叫做HashPartitioner,这个其实就是


可以看到,根据了来源数据的key,进行分区,可以看到这里,key.hashCode & Integer.MAX_VALUE 这个的作用是什么?


这个的作用其实很简单,可以看到用到的是与,而且与上,int的最大值,其实就是,不允许数据超过int的最大值而已,可以看到,int的最大值,


右边除了符号位全是1,那么与上这个数以后,如果超过了int最大值,以后,数据的key的高位,就会变成0了,也就是,不管,数据传入过来的


key是啥,范围都会被锁定在0到int最大值的范围,然后,拿着这个值,再去 跟numReduceTasks这个值,取余,的作用就很明显了,其实


就是要算出,要把这个数据,放到哪个分区中去对吧,如果比如分区我们有2个,numReduceTasks的值是2,那么,


(key.hashCode & Integer.MAX_VALUE) % numReduceTasks的值,只能是0,1对吧...这样就能把数据,分散均匀存到对应的分区里了.



2.然后我们去举个例子去看一下,首先我们新建一个package partitioner



3.然后把wordcount的代码,复制到刚创建的partitioner这个包中去



4.然后去修改一下,输出目录.



5.然后我们去设置一下,reduceTask2的数量,其实也就是设置了分区的数量的对吧,因为分区的数量和reduceTask的数量一样


然后执行看结果.



6.可以看到和之前不一样了,只有两个了,然后我们打开这两个文件去看看




7.然后我们看看结果,中如果我不想让ss和cls在一起,而想让banzhang和cls在一起怎么控制呢?



8.我们先来看一下,为什么,atguigu,cls,ss,xue在一起了,banzhang,hadoop,jiao在一起了,


因为banzhang,hadoop,jiao的key 也就是索引,行号,对numReduceTasks,也就是2取余以后,结果是0


而atguigu,cls,ss,xue,对numReduceTasks取余是1对吧.



9.然后我们去debug去看看这个,数据分区的过程,看看数据具体是怎么分的.



10.这样的话我们应该把断点打在上面,map以后,把数据溢写到分区中的时候对吧.溢写的时候对数据进行分区



应该打在上面这个位置对吧.


7.然后开始调试



8.然后进入到write方法中去看看



9.然后再进去



10.然后再进去



11.然后走到这个地方



可以看到这里有个collector.collect可以看到这个就是,咱们说的那个缓冲区 ,可以看到他这里有个


partitioner.getPartition



12.可以看到上面这里,来计算的,可以看到这个numReduceTasks是2 ,然后这个时候,读入的数据atguigu,value是1,经过,他这里默认的


hash算法,就到了分区2里面了.



13.然后继续走,可以看到,atguigu有2行对吧.可以看到走了两次



14.然后再走的话,可以看到就是下一个key了,就是ss对吧


然后我们再去看看



15.当我注释掉,上面设置的job.setNumReduceTasks(2) 然后我们再去跑跑看看



16.再走到这个地方,然后,我们进去



17.可以看到上面,如果是这样的话,因为没有设置numReduceTasks,默认是1,那么这里,partitions就是1-1 =0 ,那么这个时候就只会产生一个0号分区的文件.



18.然后执行结束就可以了.



19.上面就说了,数据经过map以后,是怎么溢写的,以及溢写的时候,具体数据是怎么分配到不同的分区的,那么,当然虽然数据被


根据hashCode,分配到了不同的分区里面,但是,我们是不能控制,哪个数据分配到哪个分区中的,那么如果想控制的话,该怎么


控制呢?


我们可以重写这个Partitioner分区对吧,我们修改它的分配规则这样就可以了.



20.要想自己控制,哪些数据分区到哪个分区中去,首先就要自己去定义一个类,去继承Partitioner这个类,然后,重写getPartition


去写自己的控制分区的代码



21.我们去看一下源码,首先找到这个hashPartitioner,然后这里要注意要找到这个hadoop3.1.3的版本的



22.然后我们要去了解一下需求,我们说要把,手机号是135的放一块,136的放一块...对吧.这样的需求,分别放到不同的分区文件中去.


这个就是我们要实现的逻辑.



23.上面我们自定义的partitioner写完以后,我们还需要把我们自己写的那个partitioner这个类,设置到job的驱动中去



24.最后还需要设置numReduceTasks的个数是5,因为不设置的话默认的是1,1的话,只有一个分区了.


上面这个工作做完了以后就说明我们的自定义分区,就做好了,并且,实现了我们的逻辑,下一节我们就用代码来实现.

最近发表
标签列表