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。
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 主 要 依 赖 于 H I V E H O M E / b i n / h i v e 和 HIVE_HOME/bin/hive 和 HIVEHOME/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