赞
踩
当你去执行一个HiveQL的时候,其实它里面做了好多东西。
现在有一批数据,数据量不算太大,当你对它们执行一个SQL,但是执行起来特别慢,为什么会这么慢?是不是要分析这个SQL它内部做了些什么?怎么去调优?让它跑起来更快呢?这些的前提是你对hive内部的机制非常了解的情况下,才会知道问题的所在。
你输入一个sql字符串,那么也就是一串字符串,hive怎么认识这个字符串?它又怎么去运行这个字符串?是不是要去解析它?是不是要检查语法有没有问题?
不管是Hive,还是其它SQL的大数据的框架,比如Spark等等,它底层的执行逻辑流程,大部分都是类似的,只是每个框架都加入了自己的东西。
要达到一个什么层度?
看到一个SQL语句,就知道它内部实现的一个过程,在脑海中映射出MR流程,在哪儿进行map,combiner,shuffle,reduce,而不是简简单单的SQL,如果你把Hive理解成就是写SQL,是很low的。比如用MR的思想把它描述出来,再比如什么join有reduce什么join没有,什么SQL有shuffle什么SQL没有等等等等。
这个不可能一次性就学会,肯定需要一个过程,一步一步来,慢慢的去训练。
这些都是面试必问的。
HiveQL执行计划
官网执行计划介绍:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain
大部分写的HiveQL,最后基本上都可以落到这两个SQL的角度,区别只是有的业务逻辑简单一些,有的复杂一些而已:
- select yyy, 聚合函数 from xxx group by yyy;
- select a.*, b.* from a join b on a.id=b.id;
下面简单介绍执行计划:
SQL on Hadoop:SQL on Hadoop的引擎,底层会做一系列的事情,会把SQL作业提交到集群上去运行,最后出来结果。这个框架对于使用者来说它是一个黑盒子,不知道里面做了些什么操作。一般情况,你在hive上执行一个SQL,然后出来结果,仅仅是这样,这种想法是绝对要不得的。
下面简单说一下执行计划。其实每个部分都需要去拆开进行仔细分析的。
1)parser:进来一个SQL字符串,将SQL解析,解析的结果是AST(抽象语法树见官网详细解释以及使用),会进行语法校验,AST本质还是字符串
2)Analyzer:语法分析,这里面还要去Meta Info里面关联查找校验,比如表存不存在、字段对不对等。然后生成QB(query block)
3)Logicl Plan:逻辑执行计划解析,进来是QB,生成一堆Opertator Tree(操作,比如select)
4)Logicl Optimizer:进行逻辑执行计划优化,生成的还是一堆Opertator Tree
5)Phsical plan:物理执行计划解析,生成 tasktree
6)Phsical Optimizer:进行物理执行计划优化,生成tasktree
7)优化后生成TaskTree,根据类别比如,是Hive SQL还是SparkSQL还是其它的,会各自提交到集群上去运行
重点是 逻辑执行计划优化和物理执行计划优化。比如图上这两个优化发生在哪里?比如是在逻辑执行计划里面还是在物理执行计划里面?
HiveQL与MapReduce
☆☆☆☆☆
面试:join用SQL来描述比较简单,就是几个表之间的关联操作,现在有个join的SQL,要你用MapReduce的代码功能来开发,你可以不会写这个代码(仅仅知道思想就行),但是要知道怎么把它的逻辑它的思想说出来,考察的点是MR的思想,你了不了解MR,join有好多种,不同的join实现的不一样,有的join有shuffle,有的join没有shuffle,这些如果用MR的路线来描述出来怎么去说?所以说一个SQL,你不能仅仅知道它就是一个join。
要到达的层度,看到一个SQL语句,脑子中就知道它内部实现的一个过程,这样理解才会更彻底。
简单过滤类-查询SQL底层MR执行原理
这是一个简单过滤的查询SQL:
select a.id,a,city, a.cate form access a where a.day=’20190414’ and a.cate= ‘奔驰’
这个SQL没有shuffle、仅仅就是过滤而已。类似之前的etl离线作业一样。
day分区在一开始从HDFS上的目录上面读的时候就已经去掉了,分区在HDFS上就是一个目录。
在map里面要做的事情:
①拆分,比如按tab键拆分,分成各个字段。
②对上面的字段,a.id,a,city, a.cate分别对应0、1、2,现在要过滤a.cate= ‘奔驰’这个,split(2),如果2这个字段为’奔驰’,就collect起来。
这个SQL是没有shuffle的,因为我们现在就是查询出a.cate= ‘奔驰’这个条件,这个条件在map阶段就已经做好了,然后就直接输出了。和之前的ETL一样,在map里做完数据清洗就直接输出了。
group by聚合类-SQL底层MR执行原理
这是一个group by聚合类的SQL:
- --按照城市分组,每个城市对大奔的访问次数
- select city, count(1) cnt from access
- where day='20190414' and cate='大奔'
- group by city
思考:用MapReduce的思想如何实现?
其实和Wordcount完全没有区别。工作中,很多类似的都是Wordcount的一个变种。
MapReduce中Wordcount如何执行?
①在map里面split过后,每个单词都会这样:(word, 1)
面试题:map类进来几个参数?map类中的map方法接收几个参数?
② shuffle:map来的 (word,1) ,根据partitioner分到reduce上面去
Hadoop中的Partitioner浅析:
https://www.cnblogs.com/zhangjxblog/p/6636765.html
③reduce: (word, 可迭代的(1,1,1,1…))
==> (word, sum(可迭代的))
面试题:map类进来几个参数?map类中的map方法接收几个参数?
下面针对上面SQL进行图解析:
city_id、类别cate这两个字段。
从HDFS上读文件,划分split,比如输入是两个split,读数据,然后进入两个map里面来,在map里拿到(city_id, 1)。
然后map之后,进行先进行本地的一个聚合combiner,算出每个task的结果,它是一个本地的reduce,好处是减少shuffle的数据量,但不是任何场景都会发生combiner,如求平均数。。
经过shuffle,根据每个特征的key,按照partitioner的一个定义分配到相应的reduce上面去执行,执行完之后把。
join类-SQL底层MR执行原理
…
执行计划优化
…
扩展1:reducebykey和groupbykey的区别,前者会发生combiner 局部聚合,而后者不会,前者获得的是相同key对应的一个元素,后者是获取元素集合。reducebykey更加适合大数据,少用groupbykey(全数据shuffle)
扩展2:map task数是由数据文件分片数决定的分片数即是map任务数,程序员只能给个期望值
扩展3:reduce task数是由输入reduce的数据的分区(partitions)数决定的即分区数为map任务数,默认是1,程序员可直接设置reduce个数来改变reduce task数,reduce task数决定来 生成的文件数。
扩展4: MR数据shuffle确定数据发往哪一个reduce分区的规则是:取key的hashcode值对分区数模。
扩展5:explain sql ;查看某sql语句的执行计划
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。