Hive原理(底层架构)

HQL是如何转换为MR任务的

1)用户接口:Client

CLI(command-line interface)、JDBC/ODBC(jdbc 访问 hive)、WEBUI(浏览器访问 hive)

​CLI:bin/hive 启动的客户端

​JDBC:通过hiveserver2 jdbc方式连接的客户端

2)元数据:Metastore

​ 元数据包括:表名、表所属的数据库(默认是 default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;

​ 默认存储在自带的 derby 数据库中,推荐使用 MySQL 存储 Metastore

3)Hadoop

​使用 HDFS 进行存储,使用 MapReduce 进行计算。

4)驱动器:Driver

​连接客户端和服务端的桥梁

5)解析器(SQL Parser)

​将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第三方工具库完成,比如 antlr;

​对 AST 进行语法分析,比如表是否存在、字段是否存在、SQL 语义是否有误。

6)编译器(Physical Plan)

​将 AST 编译生成逻辑执行计划。

7)优化器(Query Optimizer)

对逻辑执行计划进行优化。

8)执行器(Execution)

​把逻辑执行计划转换成可以运行的物理计划。对于 Hive 来说,就是 MR/Spark。

1.2 HQL 转换为 MR 任务流程说明

HQL编译为MR任务流程介绍

在这里插入图片描述

 源码部分:

在这里插入图片描述

2.2 程序入口 — CliDriver

​ 众所周知,我们执行一个 HQL 语句通常有以下几种方式:

​ 1)$HIVE_HOME/bin/hive 进入客户端,然后执行 HQL;

​ 2)$HIVE_HOME/bin/hive -e “hql”;

​ 3)$HIVE_HOME/bin/hive -f hive.sql; 执行sql文件

​ 4)先开启 hivesever2 服务端,然后通过 JDBC 方式连接远程提交 HQL。

​可以知道我们执行HQL主要依赖于 HIVEHOME/bin/hive和HIVE_HOME/bin/hive和HIVE 
HOME/bin/hive和HIVE_HOME/bin/hivesever2 两种脚本来实现提交 HQL,而在这两个脚本中,最终启动的JAVA 程序的主类为“org.apache.hadoop.hive.cli.CliDriver”,所以其实 Hive程序的入口就是“CliDriver”这个类。
 

从主方法进入 进入run方法

解析系统参数,定义标准输入输出流,解析用户参数

执行executeDriver方法

executeDriver方法中 里面有判断执行程序引擎是否mr或者spark和ez

然后初始化控制台阅读器,按行读取控制台输入语句,不断追加到已读数据后面 ,识别到分号结尾将读取内容放入到解析processLine方法中(通过输入流读取一行一行的sql,直到读到以分号结尾的语句他就会调用processLIne方法)

在processLine方法中会按照;切分读进来的数据(因为一行可能有多个;)放入集合中,然后取出集合中的命令放入processCmd方法中

调用processCmd方法,对一行一行的命令做解析
processCmd中把输入语句分为4种类型
1.退出类型(quit,exit),2.以source开头执行sql文件,3.以!开头执行shell,4.执行hql语句

第4种类型执行hql语句 核心的是processLocalCmd方法
其中有获取开始时间,HQL核心run方法,获取结束时间,打印头信息,打印结果 等

run方法传入的是sql语句run(String command) run方法调用的是重载的run(String command,boolean alreadyCompiled)方法

run方法中调用runInternal方法

进入runInternal(command,alreadyCompiled)中有2个核心方法 1.编译HQL语句compiledInternal(),2.执行execute

1.编译HQL语句中包含解析器 编译器 优化器 2.执行方法中只包含执行器

runInternal方法中调用compiledInternal

compiledInternal方法中有一个compile方法

compile方法中

#tree = ParseUtils.parse(command, ctx)生成抽象语法树方法

#sem.analyze(tree, ctx);编译器和优化器工作

进入parse解析器方法中(parseUtils类)

调用重载的parse方法

new了一个parseDriver(解析驱动),调用parse(parseDriver类)方法解析命令返回抽象语法树

#parseDriver类的parse方法中

构建词法语法解析对象new hiveLexerX()对HQL做词法语法解析 将关键词替换成tokens,将解析之后的的tokens转化成解析器,解析器工作生成最终的抽象语法树

编译器

analyze 方法中调用了analyzeInternal方法 然后继续调用重载的analyzeInternal方法

处理AST转换为QueryBlock进一步转换为 OperatorTree;

优化器

创建了一个优化器,设置全局上下文(里面放的是优化策略),通过conf文件做初始化(优化通过遍历transformations整个优化器的集合做优化)

通过生成的taskTree做物理优化

runInternal方法中调用executor方法 执行器方法

根据任务树构建mrJob 然后执行任务launchTask

化通过遍历transformations整个优化器的集合做优化)

通过生成的taskTree做物理优化

runInternal方法中调用executor方法 执行器方法

根据任务树构建mrJob 然后执行任务launchTask

猜你喜欢

转载自blog.csdn.net/weixin_51981189/article/details/128511003