Hive与Hook
Hive概述
Hive
Hook概述
Hook是一种在处理过程中拦截事件,消息或函数调用的机制。Hive Hook 可以将事件绑定在内部 Hive 的执行流程中,而无需重新编译 Hive。Hook 提供了扩展和集成外部组件的方式。根据不同的 Hook 类型,可以在不同的阶段运行。
Pre-execution Hook 在执行引擎执行查询之前被调用。这个需要在 Hive 对查询计划进行过优化之后才可以使用。
Post-execution hooks 在执行计划执行结束结果返回给用户之前被调用。
Failure-execution hooks 在执行计划失败之后被调用。
Pre-driver-run 和 post-driver-run 是在查询运行的时候运行的。
Pre-semantic-analyzer and Post-semantic-analyzer Hook 在 Hive 对查询语句进行语义分析的时候调用。
Hive查询的生命周期
Driver.run() 接收命令。
org.apache.hadoop.hive.ql.HiveDriverRunHook.preDriverRun() 读取 hive.exec.pre.hooks 中的配置,来看 pre 需要运行的 hook.
org.apache.hadoop.hive.ql.Driver.compile() 开始处理 query,并且生成 AST。
org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook 调用 preAnalyze() 方法。
Semantic analysis AST 上的语义分析。
org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook.postAnalyze() 在所有语义分析 Hook 方法执行完之后被调用。
创建物理查询计划。
Driver.execute() 准备运行 job。
org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext.run() 运行所有 hook。
org.apache.hadoop.hive.ql.hooks.ExecDriver.execute() 运行所有任务的 query。
每一个 job org.apache.hadoop.hive.ql.stats.ClientStatsPublisher.run() 都会被调用,来提供 job 的一些统计数据。间隔的默认值由 hive.exec.counters.pull.interval 来控制,默认是1000ms。
完成所有 task。
如果查询任务失败了,会调用 hive.exec.failure.hooks.
运行执行后的 Hook ExecuteWithHookContext.run()
运行 org.apache.hadoop.hive.ql.HiveDriverRunHook.postDriverRun()。注意这是在查询完成,结果返回之前执行的。
返回结果。
Hive Hook API
Hive 支持很多类型的 Hook。
PreExecute 和 PostExecute 扩展自 Hook 接口。
ExecuteWithHookContext 扩展 the Hook 接口,并且传递 HookContext 给 Hook. HookContext 封装了 Hook 所需要的所有信息。
HiveDriverRunHook 扩展 Hook 接口,运行常规的 Hive 逻辑在 Driver 上。
HiveSemanticAnalyzerHook 扩展 Hook 接口对查询进行语义分析. preAnalyze() 和 postAnalyze() 方法可以在语义分析的之前之后运行。
HiveSessionHook 扩展 Hook 接口提供 session 级别的 hooks. 当 Session 开始,hook 就会被调用。
Hive 的代码里有很多关于 Hook 的例子。
DriverTestHook 是非常简单的 HiveDriverRunHook,并且可以打印执行的命令在结果里。
PreExecutePrinter 和 PostExecutePrinter 是执行前后的 Hook,可以打印参数。
ATSHook 是运行时的 ExecuteWithHookContext,可以把运行时的 query 和 plan 发送到 YARN 的 timeline server。
EnforceReadOnlyTables 是 ExecuteWithHookContext,可以理解成检查是否有修改只读表的一个 Hook。
LineageLogger 是 ExecuteWithHookContext,可以记录 query 的血缘信息在日志文件中。
PostExecOrcFileDump 是一个运行后的 Hook,可以打印 ORC 文件的信息。
PostExecTezSummaryPrinter 是一个运行后的 Hook,可以打印 Tez 的 summary。
UpdateInputAccessTimeHook 是一个运行前的 Hook,可以更新所有的的在 query 运行前,所有的输入表的访问时间。
一个简单的 Hive Hook
现在准备写一个 Hive Hook 的例子,并且加载进去 Hive 里面。这个例子非常简单,用的是 pre-execution hook,意思就是在查询执行之前,打印 “Hello from the hook !!"
。
1.创建工程的 pom 文件。
2.在项目中引入 hive-exec 的 package。
3.创建一个 Class 实现了 Hook 接口 org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext,这个接口只有一个方法。
4.构建出的 jar 包放在 Hive 的 classpath,并且设置成 pre-execution hook。
打包hook
设置为per-execution hook
这就是使用 Hive Hook 的全部,现在就可以看到每次 Hive 语句执行之前都会看到 "Hello from hook !!"
。
Metastore Hooks
Hive 也有 metastore 的定制的 hook 来处理关于 metastore 变化的事件。 Metastore initialization hooks 会在 metastore 初始化的时候被调用。比如说保持 HBase 同步到 Hive 的 metastore 中。如果想记录外部组件在 Hive 中创建了那些 tables/databases 之类的,那么这个 Hook 就很合适了。
注意
需要注意的是 Hook 的实例不能复用。 Hook 是在正常的 Hive 流程中被调用的,所以需要避免那些影响性能的操作。
Resources
Last updated
Was this helpful?