Hive源码阅读--导读

总述

Hive的执行流程大致分为两部分,即任务的提交与返回,命令的编译与执行
前者在CliDriver类中流转,后者主要在DriverParseDriver类,核心编译在BaseSemanticAnalyzerQueryPlan类中。

任务的提交与返回

调用顺序:

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架构设计

Hive的概念

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必须知道的知识点:

  • 由Facebook实现并开源
  • 是基于Hadoop的一个数据仓库工具
  • 存储的数据底层还是存储在HDFS上
  • Hive将HDFS上的结构化数据映射为一张数据库表,类似于mysql表
  • Hive提供HQL查询功能
  • Hive的本质是把SQL语句转换为MR任务执行
  • Hive用户更集中于业务逻辑
  • Hive需要一个保存抽象信息的数据库

Hive的架构设计

Hive源码阅读--导读_第1张图片
任何一个对Hive有了解的人,应该都见过这张图,他很清楚的描述了Hive的客户端与Hive内部的架构。
在整个架构中最核心的就是Hive的Driver,他其实分为四块:

Driver			--->	驱动器
Compiler		--->	编译器
Optimizer		--->	优化器
Executor		--->	执行器

他们其实只做了一件事情:如何将SQL变成优秀的MR任务

MapReduce实现基本SQL操作的原理

MR的执行原理

举个

张三,李四,王五三个人打算斗地主,找到了一副年代久远的牌,但是不确定这副牌是否够54张。
1.张三手速很快,所以张三一个人数牌,数完50张,牌不够。
2.将牌分为了三份,三个人分别数一份牌,数完后张三手里有20张,李四手里有14张,王五手里有16张,加一起只有50张牌,牌不够。

假设平均一个人数一张牌要1S,那么第一种情况要50S,第二种情况要20S+汇总时间,第二种情况肯定比第一种情况快。

这个例子其实就对应生成环境中的两种情况,第一种情况是纵向扩展,把机器的性能拼命提高,比如超算,天河二号;第二种情况是横向扩展,一台干不完的活我三台干。

既然工作机器数增加了,那么肯定就有分发,干活,汇总三个阶段,分发就是map,汇总就是reduce。这种解决方案就叫做MapReduce。

我们举三个最典型的例子。

join的实现

sql语句:

select u.name,o.orderid from order o join user u on o.uid=u.uid;

实现思路图:
Hive源码阅读--导读_第2张图片

  • 将连接字段作为key值,表标记+查询字段作为value
  • shuffle时将同一key(同一uid)划分为一组
  • reduce时进行笛卡尔积连接

group by的实现

sql语句:

select rank,isonline,count(*) from city group by rank,isonline;

实现思路图:
Hive源码阅读--导读_第3张图片

  • 将分组字段聚合为map构建key,同时将聚合函数结果作为value(本地shuffle)
  • shuffle时将相同key划分在一起
  • reduce再次聚合
  • 两次聚合降低网络IO与本地压力

distinct的实现

sql语句:

select dealid,count(distinct uid) num from order group by dealid;

实现思路图:
Hive源码阅读--导读_第4张图片

  • 查询字段组合为map作为key,聚合函数结果作为value,分组字段作为partitionkey
  • shuffle时按照partitionKey进行分组
  • reduce对key去重后再聚合

HQL怎么转换为MR

六个阶段

  • Antlr定义SQL的语法规则,完成SQL词法、语法解析,将SQL转换为抽象语法树AST Tree
  • 遍历AST Tree,抽象出查询的基本组成单位QueryBlock
  • 遍历QueryBlock,翻译为执行操作树OperatorTree
  • 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少Shuffle的数量。
  • 遍历OperatorTree,翻译为MR任务
  • 物理层优化器进行MR任务的变化,生成最终的执行计划

源码流程图

流程图请结合Hive源码解析专栏阅读。
Hive源码阅读--导读_第5张图片

你可能感兴趣的:(#,---Hive源码解析,java,hive)