面试必问 | 一文轻松搞定MapReduce、HQL执行原理
Editor's Note
如果你是一名数据工程师,还是一名吃货,MapReduce、HQL执行原理,你就可以在美味中吸收消化了..
The following article is from 憋七工作室 Author 憋七
如果你是一名数据工程师,还是一名吃货,那这篇文章应该没那么枯燥了。
今天用日料Sushi来一起走进MapReduce与HQL执行过程!轻松愉快美味~
##Ps:本人是个吃货(但人又很瘦的那种),尤其爱吃刺身日料,而且一说到吃就很激动,小胃已经锻炼的杠杠的了。
先简单介绍一下什么是Sushi,就是寿司。寿司也分很多种,本次就用手握寿司来生动形象的描述MR的原理和过程。
进入MapReduce之前的阶段
因为是对比讲解,所以从准备阶段开始,在准备阶段我们要准备好食材,食材就好比我们准备阶段的数据,食材有好有坏,数据同样也有好坏之分,一般想要得出的数据准确无误,都要准备“上好食材”,脏数据差数据尽可能避免,做好的sushi重点也是要好原料,新鲜度和品质占一部分,厨师的手艺也很关键。
我们这里分3个厨师吧,分别叫:M、S、R。
开始说下我们的原料食材,要做手握寿司,三文鱼、金枪鱼、干海苔、鱼子酱、山葵酱、醋饭,其他小的细节就不提了,而且也只用两种鱼类做参考。
准备好这些“数据”后开始进入下一阶段。
M厨师的Map阶段
整块三文鱼和金枪鱼放到面前,开切!切鱼也有很多讲究(刀、角度、还有姿势),在这里就不过多描述了,每片切1厘米左右,备用。
转回来在MapReduce中,首先M厨师上场,根据文件个数分配Mapper Task个数,M厨师依照下图SQL,再根据自己的手法做切分,当然手法是固定的,不能有偏见。主料和配料都会在这步做切分。
这一步主要是根据不同的鱼类进行切分,每个种类应切多少片呢,一般是按照DFS块大小来切,当然也可以用这个参数mapred.min.split.size自定义。
(join,SQL:select u.name, o.orderid from order o join user u on o.uid = u.uid;普通两表join,只要在value上打上标记就可以了)
(group by,SQL:select uid, name, count(*) from student group by uid, name;将GroupBy的字段组合为map的输出key值)
(count(distinct),SQL:select name, count(distinct uid) cnt from student group by name;将GroupBy字段和Distinct字段组合为map输出key)
下一步到S厨师,Shuffle阶段。
(本次没让负责Combine阶段的C厨师介入)
这步非常关键!也是最核心的,为什么核心呢?是因为衔接Map阶段和Reduce阶段之间的,核心的中间桥梁。
这一步是对食材进行分类,分类为什么核心,这次分类不是按照同种类区分,而是按照最终呈现的菜品进行分类。比如一贯寿司中,要几片干海苔,几片三文鱼,多少量的饭,多少量的鱼子酱等等。要注意的是,S厨师只是进行分类,并不负责将这些食材组合成最终的菜品,最终组合是R厨师的工作。试想一下,如果S厨师没学习过日料厨艺,也没吃过寿司,可能就会在某一贯寿司上分10片三文鱼,在另一贯寿司上分2片三文鱼,(可能是有自家亲戚或哥们来关顾才会这么分吧),这样分类会给R厨师造成很大难度,这种情况一会详细介绍。
转回到在MapReduce中,S厨师依据最终菜品进行食材分类,分类手法也是不一样的,根据SQL分不同方式分类,Shuffle阶段细分的话会分Map Task阶段的Shuffle和Reduce Task阶段的Shuffle:
Mapper Task输出时会开启一个环形内存缓冲区,并且在配置文件里有个设定的阈值(默认80%,可以改),当发现使用量到达这个内存阈值的时候,就会把这80%的内容写到磁盘上,这个过程叫分隔,Map Shuffle过程过后会生成1个或者多个分隔文件
Reduce Task输入时会分为两个任务:
1.Copy Map输出:直接Copy Map Shuffle的最后一步
2.Merge:基于JVM的heap size设置的内存缓冲区
最后Reduce Task不断合并后,会写到内存中或者磁盘中
(join,SQL:select u.name, o.orderid from order o join user u on o.uid = u.uid;每个Mapper Task按照key进行分类)
(group by,SQL:select uid, name, count(*) cnt from student group by uid, name;同样按照Key值分类)
(count(distinct),SQL:select name, count(distinct uid) cnt from student group by name;这里图中保留出partition key,大家能看的清楚些,和Group by 不同的是会将distinct字段和group by字段全部已key的形式放到内存中,数据量大的时候会造成“内急”OOM情况,所以很多时候要避免count和distinct的cp组合)
最后到R厨师,Reduce阶段
组合排序,这一步将S厨师分类出的食材进行最终组合,组合成最终菜品展现给顾客,M、S、R三个厨师都只做自己的工作,不会有相互的交流(甚至连眼神的那种都没有),上游给到什么就做什么,这就是机器干活的弊端。最终三文鱼寿司,实在是不好描述,给大家个搜狗emoji🍣,大家觉得小的话,可以从大众点评上搜索一番,相信大家可以找到自己理想中的图片的。
转回MapReduce中,R厨师会进行去重,排序、输出,在此阶段会生成Reducer Task,再利用sum函数,将数据写到HDFS中
(join,SQL:select u.name, o.orderid from order o join user u on o.uid = u.uid;按照标记判断来源,进行合并排序)
(group by,SQL:select uid, name, count(*) cnt from student group by uid, name;在reduce阶段保存LastKey区分不同的key,进行计数、去重)
(count(distinct),SQL:select name, count(distinct uid) cnt from student group by name;和Group by雷同进行计数,去重)
在看 数据倾斜
咱们在S厨师留了个话题,如果S厨师分了10片三文鱼给一贯寿司,那R厨师要怎么办呢,是的,二话不说将10片放到定量的米饭上,话说R厨师也算是个有点傻了,R厨师会把所有寿司全部做好后,才会给到顾客,而不是做好一个交付一个,那10片寿司放到米饭上确实不稳,组合时间会比较长,而且经常会放到第9片的时候,前8片塌了......这也是我们经常看到任务长时间在99%的状态,有时候99%还会往回倒退,我一般看到这个场面的时候会表现出托腮发呆状崩溃。
还有一种情况,大小表关联产生的数据倾斜,这种情况解决比较简单,使用map join将小表全部塞到mapper task里面。
正好借鉴在发表这篇文章前几天,和我并肩作战5年的weiwei小姐姐分享的数据倾斜解决方案。
1.Filter过滤
将冲突数据进行直接过滤,要根据业务制定,但有时候业务自己也是傻傻分不清楚,拍脑袋全都要,对待如此要求确实也没什么可理论的,这种也不是好办法,遇到问题就解决问题好了
2.参数强行干预
既然自己内部解决不了,那就让hive强行设立法案,来帮助单个任务内部解决吧,相关法案有一大堆,这里只例举几个,其他的可自行百度,百度上已经有现成的可以借鉴;
mapred.map.tasks.speculative.execution
mapred.reduce.tasks.speculative.execution
mapred.min.split.size
...
3.大Key歧视方案
将大Key单独做一个MapReduce流程进行处理,但这个方案得根据业务可行性来处理,基本业务场景很少能支持这种方案,毕竟在全球任何地方都不允许歧视,也包括计算机内部。
4.Key值友善处理
咱们都处在友善之邦,也是友善的人,这种友善的处理方案还是最适合的,那如何友善呢,详细说这个方案。
举个例子:求每个城市有多少用户登录(用户已去重)
这个例子按照uid将城市维度进行打散,打成均值,保证每个Key雨露均沾,均沾count后再进行sum。这个例子是最简单的场景,实际可能会比较复杂,但是核心思想就是把group by 的Key打散。用rand或者hash规则都可以,当然也可以用时间。
山葵和芥末不是一个东西哦
好了,Sushi做完了,可以开动品尝了,吃Sushi正确吃法不是把山葵放到酱油里!!!而是把山葵夹到刺身上,尽量将刺身去蘸将油料,而且要一口塞到嘴中,尽量吃刚做好的,保持食材新鲜进入到嘴中,评判一家寿司店好不好首先要看食材,第二要看厨师,寿司要避免在手中过长时间的制作,避免人体的温度传到寿司中,从而影响口感。
#PS:山葵和芥末不是一个东西哦~
以上MapReduce环节在数仓面试中是都会问到的高频必问知识点之一!
如果大家喜欢吃,也喜欢捣鼓数据,也可以共同交流。如果有什么我表达欠妥的地方,也希望给出建议,一起成长一起进步。戳:数据交流群
如果您喜欢本文,欢迎点击右上角,把文章分享到朋友圈~~
戳文末“阅读原文”,到公众号菜单栏 即可直达上面干货优质文章
欢迎加入中台|数仓技术交流群。戳:数据交流群!
进群方式:请加微信(微信号:iom1128),回复:数据,通过审核会自动拉你进群。
(备注:行业-职位-城市)
Q: 关于数据仓库,你还想了解什么?
更多精彩,请戳"阅读原文"到"大厂案例"查看
!关注不迷路~ 各种福利、资源定期分享!