网站首页 > 文章精选 正文
我们通过一个案例来说明,比如我们要将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的话,只有一个分区了.
上面这个工作做完了以后就说明我们的自定义分区,就做好了,并且,实现了我们的逻辑,下一节我们就用代码来实现.
猜你喜欢
- 2025-05-10 Java手写一个bitmap(java手写代码)
- 2025-05-10 MySQL有哪些实现方式?何为插入,何为更新?
- 2025-05-10 自学 C++ 第 6 课 二维数组找最值
- 2025-05-10 斐波那契查找算法(斐波那契查找算法java)
- 2025-05-10 YARN 资源调度器 CapacityScheduler 原理
- 2025-05-10 8张图带你全面了解kafka的核心机制
- 2025-05-10 java数据类型的转换以及精度丢失(java中基本数据类型转换)
- 2025-05-10 C语言中用宏实现求两个数中的最大数
- 2025-05-10 异或的魅力!图解「数组中两个数的最大异或值」
- 2025-05-10 基础函数20例,案例解读,再不掌握就真的Out了
- 05-14TS,TypeScript,Windows环境下构建环境,安装、编译且运行
- 05-14TypeScript 也能开发AI应用了!
- 05-14搞懂 TypeScript 装饰器
- 05-14前端小哥哥:如何使用typescript开发实战项目?
- 05-14在 React 项目中,一般怎么处理错误?
- 05-14react19 常用状态管理
- 05-14Vue3开发极简入门(2):TypeScript定义对象类型
- 05-14C#与TypeScript语法深度对比
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)