无论你通过哪种方式连接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

Hive Query生命周期 —— 钩子(Hook)函数篇的更多相关文章

  1. Vue的钩子函数[路由导航守卫、keep-alive、生命周期钩子]

    前言 说到Vue的钩子函数,可能很多人只停留在一些很简单常用的钩子(created,mounted),而且对于里面的区别,什么时候该用什么钩子,并没有仔细的去研究过,且Vue的生命周期在面试中也算是比 ...

  2. vue之生命周期钩子函数之运用

    一.什么是生命周期钩子函数: 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行 ...

  3. Vue生命周期 钩子函数和组件传值

    Vue生命周期 钩子函数 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等. 同时在这个过程中也会运行一 ...

  4. vue-实例生命周期钩子(不太明白)

    每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项}) 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要 ...

  5. vue生命周期图示中英文版Vue实例生命周期钩子

    vue生命周期图示中英文版Vue实例生命周期钩子知乎上近日有人发起了一个 “react 是不是比 vue 牛皮,为什么?” 的问题,Vue.js 作者尤雨溪12月4日正面回应了该问题.以下是尤雨溪回复 ...

  6. vue学习三:生命周期钩子

    生命周期钩子介绍: 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行一些叫做生 ...

  7. Vue学习之生命周期钩子小结(四)

    一.生命周期钩子(函数): 1.每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运 ...

  8. Vue_(组件)实例生命周期钩子

    Vue生命周期中文文档 传送门 Vue生命周期:Vue实例从创建到销毁的过程,称为Vue的生命周期: Vue生命周期钩子:又称为Vue生命周期钩子方法/函数,是Vue为开发者提供的方法,我们可以通过这 ...

  9. 前端(二十)—— vue介绍:引用vue、vue实例、实例生命周期钩子

    vue 一.认识Vue 定义:一个构建数据驱动的 web 界面的渐进式框架 优点: 1.可以完全通过客户端浏览器渲染页面,服务器端只提供数据 2.方便构建单页面应用程序(SPA) 3.数据驱动 =&g ...

随机推荐

  1. Jwt令牌创建

    添加依赖 <dependencies> <!-- jwt --> <dependency> <groupId>io.jsonwebtoken</g ...

  2. I/O方式(本章最重要)

    目录 程序查询方式 程序查询方式接口结构 例题 本节回顾 程序中断方式 中断的基本概念 工作流程 中断请求 分类 中断请求标记 中断响应 判优实现 优先级设置 中断处理过程 中断隐指令 硬件向量法 中 ...

  3. JavaSE11-多态&抽象类&接口

    1.多态 1.1 多态的概述 什么是多态 同一个对象,在不同时刻表现出来的不同形态 多态的前提 要有继承或实现关系 要有方法的重写 要有父类引用指向子类对象 1.2 多态中的成员访问特点 成员访问特点 ...

  4. html 09-HTML5详解(三)

    09-HTML5详解(三) #Web 存储 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以document. ...

  5. Kali Linux破解wifi密码(无须外置网卡)

    环境准备:  方式一(选择该方式):Kali Linux.笔记本一台.U盘(至少8G)  方式二:Kali Linux.外置网卡.笔记本一台.VM   特别说明,主要是使用方式一进行破解,如果有外置网 ...

  6. Java并发包之 CopyOnWriteArrayList

    大家在学习Java的过程中,或者工作中,始终都绕不开集合.在单线程环境下,ArrayList就可以满足要求.多线程时,我们可以使用CopyOnWriteArrayList来保证数据安全.下面我们一起来 ...

  7. JDK8新特性详解(二)

    Stream流的使用 流操作是Java8提供一个重要新特性,它允许开发人员以声明性方式处理集合,其核心类库主要改进了对集合类的 API和新增Stream操作.Stream类中每一个方法都对应集合上的一 ...

  8. CCNP之MERG实验报告

    MGRE实验报告 一.实验要求: 1.R5为ISP,只能配置IP地址 2.R1--R3间建立MGRE环境,且使用EIGRP来学习各自环回 3.R4可以正常访问R5的环回 4.R1与R5进行chap认证 ...

  9. Windows 系统下Vue的安装及环境搭建

    Hope to help those in need and those who use Vue for the first time. 1.获得并安装node.js.nodejs官网:https:/ ...

  10. CentOS8/Windows 安装RabbitMQ

    Centos8安装rabbitmq 1.安装erlang(rabbitmq是用erlang语言开发的,erlang版本需要22.x以上) yum install erlang 2.下载rabbitmq ...