Hive的执行流程大致分为两部分,即任务的提交与返回
,命令的编译与执行
。
前者在CliDriver
类中流转,后者主要在Driver
与ParseDriver
类,核心编译在BaseSemanticAnalyzer
和QueryPlan
类中。
调用顺序:
main --(
程序的开始
)–>
run --(任务的开始,读取用户传参与相关配置,初始化日志
)–>
executeDriver --(确保传入的语句是一条完整的SQL或命令
)–>
processLine --(上保险,确保任务可以中断
)–>
processCmd --(识别命令的类型,交给相对于的处理方法
)–>
processLocalCmd --(选择SQL命令的处理器,默认是Driver
)–>
Driver (到这里算提交完成
)
Hive源码阅读–作业的入口–CliDriver(main+run)
Hive源码阅读–作业的提交–executeDriver
Hive源码阅读–作业的准备–processLine
Hive源码阅读–作业的执行–processCmd
Hive源码阅读–命令的执行与返回–processLocalCmd
命令的编译流程为:
第一阶段 --(
Driver
)–>
SQL–(ParseDriver
)–>
AST(Abstract Syntax Tree)–(BaseSemanticAnalyzer
)–>
Task(MapRedTask,FetchTask)–(QueryPlan
)–>
QueryPlan(Task集合)—(Driver
)–>
Job(Yarn)
Hive源码阅读–SQL的语法解析和语义分析–Driver
Hive源码阅读–SQL on JOB–ParseDriver/BaseSemanticAnalyzer/QueryPlan
Hive源码阅读–词法、语法解析–HiveLexerX/HiveParser
Hive源码阅读–查询分析器–SemanticAnalyzer
Hive依赖于HDFS存储数据,Hive将HQL转换为MR进行执行,所以说Hive是基于Hadoop的一个数据仓库工具,实质上就是一款基于HDFS的MR计算框架,对存储在HDFS中的数据进行分析与查询。
假如我们在HDFS中有一个结构化的数据:
1,zhangsan,20
2,lisi,18
3,wangwu,21
然后用Hive抽象的保存他:
表名:huamingce
字段:id,name,age
如果使用mr去取这个文件的数据的话,肯定得写几十行代码,如果使用Hive的手段去取:
select * from huamingce;
这其实也是现在程序开发的一个缩影,底层逻辑很复杂,但是可以封装的很简单。
程序的开发越来越趋向于web化,轻捷化,拖缀化。
关于hive必须知道的知识点:
任何一个对Hive有了解的人,应该都见过这张图,他很清楚的描述了Hive的客户端与Hive内部的架构。
在整个架构中最核心的就是Hive的Driver,他其实分为四块:
Driver ---> 驱动器
Compiler ---> 编译器
Optimizer ---> 优化器
Executor ---> 执行器
他们其实只做了一件事情:如何将SQL变成优秀的MR任务
举个
张三,李四,王五三个人打算斗地主,找到了一副年代久远的牌,但是不确定这副牌是否够54张。
1.张三手速很快,所以张三一个人数牌,数完50张,牌不够。
2.将牌分为了三份,三个人分别数一份牌,数完后张三手里有20张,李四手里有14张,王五手里有16张,加一起只有50张牌,牌不够。
假设平均一个人数一张牌要1S,那么第一种情况要50S,第二种情况要20S+汇总时间,第二种情况肯定比第一种情况快。
这个例子其实就对应生成环境中的两种情况,第一种情况是纵向扩展,把机器的性能拼命提高,比如超算,天河二号;第二种情况是横向扩展,一台干不完的活我三台干。
既然工作机器数增加了,那么肯定就有分发,干活,汇总三个阶段,分发就是map,汇总就是reduce。这种解决方案就叫做MapReduce。
我们举三个最典型的例子。
sql语句:
select u.name,o.orderid from order o join user u on o.uid=u.uid;
sql语句:
select rank,isonline,count(*) from city group by rank,isonline;
sql语句:
select dealid,count(distinct uid) num from order group by dealid;
Antlr
定义SQL
的语法规则,完成SQL
词法、语法解析,将SQL
转换为抽象语法树AST Tree
AST Tree
,抽象出查询的基本组成单位QueryBlock
QueryBlock
,翻译为执行操作树OperatorTree
OperatorTree
变换,合并不必要的ReduceSinkOperator
,减少Shuffle
的数量。OperatorTree
,翻译为MR任务