vlambda博客
学习文章列表

面试必问 | 一文轻松搞定MapReduce、HQL执行原理


如果你是一名数据工程师,还是一名吃货,那这篇文章应该没那么枯燥了。


今天用日料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上打上标记就可以了)


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(group by,SQL:select uid, name, count(*) from student group by uid, name;将GroupBy的字段组合为map的输出key值)


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(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不断合并后,会写到内存中或者磁盘中

面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(join,SQL:select u.name, o.orderid from order o join user u on o.uid = u.uid;每个Mapper Task按照key进行分类)


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(group by,SQL:select uid, name, count(*) cnt  from student group by uid, name;同样按照Key值分类)


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(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中

面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(join,SQL:select u.name, o.orderid from order o join user u on o.uid = u.uid;按照标记判断来源,进行合并排序)


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(group by,SQL:select uid, name, count(*) cnt from student group by uid, name;在reduce阶段保存LastKey区分不同的key,进行计数、去重)


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(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小姐姐分享的数据倾斜解决方案。

面试必问 | 一文轻松搞定MapReduce、HQL执行原理数据仓库与Python大数据推荐搜索
数据倾斜
Hive调优
面试
模型


1.Filter过滤

将冲突数据进行直接过滤,要根据业务制定,但有时候业务自己也是傻傻分不清楚,拍脑袋全都要,对待如此要求确实也没什么可理论的,这种也不是好办法,遇到问题就解决问题好了


2.参数强行干预

既然自己内部解决不了,那就让hive强行设立法案,来帮助单个任务内部解决吧,相关法案有一大堆,这里只例举几个,其他的可自行百度,百度上已经有现成的可以借鉴;

mapred.map.tasks.speculative.execution

mapred.reduce.tasks.speculative.execution

mapred.min.split.size

...


3.大Key歧视方案

将大Key单独做一个MapReduce流程进行处理,但这个方案得根据业务可行性来处理,基本业务场景很少能支持这种方案,毕竟在全球任何地方都不允许歧视,也包括计算机内部。


4.Key值友善处理

咱们都处在友善之邦,也是友善的人,这种友善的处理方案还是最适合的,那如何友善呢,详细说这个方案。


举个例子:求每个城市有多少用户登录(用户已去重

面试必问 | 一文轻松搞定MapReduce、HQL执行原理

       

这个例子按照uid将城市维度进行打散,打成均值,保证每个Key雨露均沾,均沾count后再进行sum。这个例子是最简单的场景,实际可能会比较复杂,但是核心思想就是把group by 的Key打散。用rand或者hash规则都可以,当然也可以用时间。



  山葵和芥末不是一个东西哦  


好了,Sushi做完了,可以开动品尝了,吃Sushi正确吃法不是把山葵放到酱油里!!!而是把山葵夹到刺身上,尽量将刺身去蘸将油料,而且要一口塞到嘴中,尽量吃刚做好的,保持食材新鲜进入到嘴中,评判一家寿司店好不好首先要看食材,第二要看厨师,寿司要避免在手中过长时间的制作,避免人体的温度传到寿司中,从而影响口感。


#PS:山葵和芥末不是一个东西哦~

        

以上MapReduce环节在数仓面试中是都会问到的高频必问知识点之一!

       

如果大家喜欢吃,也喜欢捣鼓数据,也可以共同交流。如果有什么我表达欠妥的地方,也希望给出建议,一起成长一起进步。戳:


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

面试必问 | 一文轻松搞定MapReduce、HQL执行原理
面试必问 | 一文轻松搞定MapReduce、HQL执行原理
重磅推荐


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

面试必问 | 一文轻松搞定MapReduce、HQL执行原理






面试必问 | 一文轻松搞定MapReduce、HQL执行原理


欢迎加入中台|数仓技术交流群。戳:!


面试必问 | 一文轻松搞定MapReduce、HQL执行原理

(备注:行业-职位-城市)

Q: 关于数据仓库,你还想了解什么?


更多精彩,请戳"阅读原文"到"大厂案例"查看

   

关注不迷路~ 各种福利、资源定期分享!


你也「 在看 」吗? 👇

戳原文,升职加薪!