无论你通过哪种方式连接Hive(如Hive Cli、HiveServer2),一个HQL语句都要经过Driver的解析和执行,主要涉及HQL解析、编译、优化器处理、执行器执行四个方面。

以Hive目前原生支持计算引擎MapReduce为例,具体处理流程如下:

  1. HQL解析生成AST语法树Antlr定义SQL的语法规则,完成SQL词法和语法解析,将SQL转化为抽象语法树AST Tree
  2. 语法分析得到QueryBlock遍历AST Tree,抽象出查询的基本组成单元QueryBlock
  3. 生成逻辑执行计划遍历QueryBlock,翻译为执行操作树Operator Tree
  4. Logical Optimizer Operator进行逻辑优化逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
  5. 生成物理执行计划Task Plan遍历Operator Tree,翻译为MapReduce任务
  6. 物理优化Task Tree,构建执行计划QueryPlan物理层优化器进行MapReduce任务的变换,生成最终的执行计划
  7. 表以及其他操作鉴权
  8. 执行引擎执行

在Hive Query整个生命周期中,会有如下钩子函数被执行:

HiveDriverRunHook的preDriverRun

该钩子函数由参数hive.exec.driver.run.hooks控制,决定要运行的pre hooks,多个钩子实现类以逗号间隔,钩子需实现 org.apache.hadoop.hive.ql.HiveDriverRunHook接口。

HiveSemanticAnalyzerHook的preAnalyze

在Driver开始run之前,HQL经过解析会进入编译阶段的语法分析,而在语法分析前会经过钩子HiveSemanticAnalyzerHook的preAnalyze方法处理。该钩子函数由hive.semantic.analyzer.hook配置,钩子需实现org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHook接口。

HiveSemanticAnalyzerHook的postAnalyze

与preAnalyze同属于一个钩子类,配置参数相同,会执行所有配置的语义分析hooks,但它位于Hive的语法分析之后,可以获取HQL的输入和输出表及分区信息,以及语法分析得到的task信息,由此可以判断是否是需要分布式执行的任务,以及执行引擎是什么。

生成执行计划之前的redactor钩子

该钩子由hive.exec.query.redactor.hooks配置,多个实现类以逗号间隔,钩子需继承org.apache.hadoop.hive.ql.hooks.Redactor抽象类,并替换redactQuery方法。

这个钩子函数是在语法分析之后,生成QueryPlan之前,所以执行它的时候语法分析已完成,具体要跑的任务已定,这个钩子的目的在于完成QueryString的替换,比如QueryString中包含敏感的表或字段信息,在这里都可以完成替换,从而在Yarn的RM界面或其他方式查询该任务的时候,会显示经过替换后的HQL。

task执行前的preExecutionHook

在执行计划QueryPlan生成完,并通过鉴权后,就会执行具体的task,而task执行之前会经过一个钩子函数,钩子函数由hive.exec.pre.hooks配置,多个钩子实现类以逗号间隔。实现方式:

1)实现org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext

通过实现该接口的run方法,执行所有的pre-execution hooks

// Pre/Post Execute Hook can run with the HookContext
public interface ExecuteWithHookContext extends Hook { /** hookContext: The hook context passed to each hooks.
* HookContext带有执行计划、Hive的配置信息、Lineage、UGI、提交的用户以及输入输出表等信息
*/
void run(HookContext hookContext) throws Exception;
}

2)实现org.apache.hadoop.hive.ql.hooks.PreExecute

该接口的run方法已经标注为过时,并且相对于ExecuteWithHookContext,PreExecute提供的信息可能不能完全满足我们的业务需求。

public interface PreExecute extends Hook {

/**
* The run command that is called just before the execution of the query.
* SessionState、UGI、HQL输入表及分区信息,HQL输出表、分区以及本地和hdfs文件目录信息
*/
@Deprecated
public void run(SessionState sess, Set<ReadEntity> inputs,Set<WriteEntity> outputs, UserGroupInformation ugi) throws Exception;
}

 task执行失败时的ON_FAILURE_HOOKS

task执行失败时,Hive会调用这个hook执行一些处理措施。该钩子由参数hive.exec.failure.hooks配置,多个钩子实现类以逗号间隔。需实实现org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext接口。

task执行完成时的postExecutionHook

在task任务执行完成后执行。如果task失败,会先执行ON_FAILURE_HOOKS,之后执行postExecutionHook,该钩子由参数hive.exec.post.hooks指定的hooks(多个钩子实现类以逗号间隔)执行post execution hooks。实现方式:

1)实现org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext

2)实现org.apache.hadoop.hive.ql.hooks.PostExecute

ExecuteWithHookContext和PostExecute跟分别与上述task执行前的preExecutionHook、PreExecute对应,这里不再赘述。

 

HiveDriverRunHook的postDriverRun

在查询完成运行之后以及将结果返回给客户端之前执行,与preDriverRun对应。

此外,Hive中已经有一些内置实现的hook,下面举一些例子以及它们的主要作用:

ATSHook:实现了ExecuteWithHookContext,将查询和计划信息推送到Yarn App Timeline Server。

DriverTestHook:实现了HiveDriverRunHook的preDriverRun方法(对postDriverRun是空实现),用于打印输出的命令

EnforceReadOnlyTables:pre execute hook,实现了ExecuteWithHookContext,用于阻止修改只读表。

LineageLogger:实现了ExecuteWithHookContext,它将查询的血统信息记录到日志文件中。LineageInfo包含有关query血统的所有信息。

PreExecutePrinter和PostExecutePrinter:pre和post hook的示例,它将参数打印输出。

PostExecTezSummaryPrinter:post execution hook,实现了ExecuteWithHookContext,可以打印Hive Tez计数器的相关信息。

PostExecOrcFileDump:post execution hook,实现了ExecuteWithHookContext,用于打印ORC文件信息。

UpdateInputAccessTimeHook:pre execution hook,可在运行查询之前更新所有输入表的访问时间。

特别强调一下LineageLogger和LineageInfo,对于做Hive血缘关系分析很有参考价值,当然Hive血缘分析不是本篇文章的重点,这里先不做展开。

通过对上面Hive中hook的执行"位置"和作用,以及Hive本身实现的一些Hook,分析可知:自定义hook,比如实现一个pre execution hook。

首先在maven的pom中引入hive-exec的依赖,如:

<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.0</version>
</dependency>

此外,还需创建一个实现ExecuteWithHookContext的类,实现其中的run方法,并设置相应的参数,使自定义的hook类生效。

最后,通过一张图,来对Hive Hook做个总结:

关联文章:
Hive Join优化
Apache Hive

最新文章

  1. maven学习(上)- 基本入门用法
  2. 偶遇到 java.util.ConcurrentModificationException 的异常
  3. PHP基于数组的分页函数(核心函数array_slice())
  4. C++ Qt 框架静态编译 操作记录
  5. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q40-Q44)
  6. IOS第四天(3:数组的排序和乱序)
  7. Android模拟器使用教程
  8. [iOS]iPhone利用&lt;极光推送&gt;实现远程推送
  9. C# IO操作磁盘上的txt
  10. android 开发工具(转)
  11. nginx添加第三方模块
  12. codeforces432D Prefixes and Suffixes(kmp+dp)
  13. U3D学习使用笔记(四)
  14. [原]点击按钮,表格隔行变色:偶数行为黄色背景,奇数行为默认颜色。通过table的getElementsByTagName取得所有的tr,依次遍历,如果是偶数就…………。
  15. php优秀框架codeigniter学习系列——CI_Lang类学习
  16. 暴走Python之运算符与条件语句
  17. (水题)P1424 小鱼的航程(改进版) 洛谷
  18. await这个关键词以及asyncio.wait asyncio.gather
  19. C/C++中如何在main()函数之前执行一条语句?
  20. Tomcat修改用户名密码教程

热门文章

  1. Hyper-v 虚拟机使用NAT方式连接网络
  2. springmvc表单标签库的使用
  3. Eureka系列(七) 服务下线Server端具体实现
  4. [BUUCTF] 真的很杂
  5. 对着爬虫网页HTML学习Python正则表达式re
  6. CODING DevOps 线下沙龙回顾二:SDK 测试最佳实践
  7. 微服务 - 服务消费(七)Feign
  8. 进入mysql数据库修改密码
  9. idea中surround with
  10. 为什么不建议把数据库部署在Docker容器内?