Hive 动态分区剪裁原理

网友投稿 1246 2022-05-30

1      介绍

当一个大表和小表进行join,大表的join列是分区列,小表的join列不是分区列时,Hive的动态分区剪裁就会收集小表的join列的集合,发送给tez am, am在为大表计算split时,会根据集合的值过滤大表不需要扫描的分区,从而减少数据扫描量,提高sql执行性能。

2      使用

针对hive 3.1.0版本,有如下参数与动态分区剪裁有关

参数名

默认值

描述

hive.tez.dynamic.partition.pruning

true

是否开启动态分区剪裁

hive.tez.dynamic.partition.pruning.extended

true

hive.tez.dynamic.partition.pruning.max.event.size

1*1024*1024L

AppMasterEventOperator在运行时发送给AM的数量最大值。单位字节。

hive.tez.dynamic.partition.pruning.max.data.size

100*1024*1024L

Hive在编译过程中估计的AppMasterEventOperator处理数据量最大值。单位字节。

对于TPC-DS query6, 开启动态分区剪裁后,query6的执行时间由115s降到了58s ,性能提升1.98倍。

3      原理

3.1      逻辑优化

3.1.1        Join谓词合成

动态分区剪裁在逻辑优化的PredicatePushDown规则前增加了SyntheticJoinPredicate规则,该规则会为每个join的父节点生成一个合成的条件。

如上图,SynthicJoinPredicate会为每个join operator生成两个父Filter Operator, Filter的谓词条件为a in (select b from other table)。

为了能够表达动态列表的表达式,Hive中引入了ExprNodeDynamicListDesc类,该类有三个参数:数据类型、数据源Operator,数据源的列表达式。

对于inner join,在join的所有父节点都会生成谓词,对于left join和right join,只会在右和左侧的父节点生成谓词。

3.1.2        谓词下推

在这一步会借助已有的PredicatePushDown逻辑将谓词条件尽可能的下推到TableScanOperator。

3.2      物理优化

3.2.1        动态分区裁剪优化(DynamicPartitionPruningOptimization)

在遍历Operator树时,当遇到了符合条件的FilterOperator会执行动态分区剪裁优化。条件为: FilterOperator的父节点为TableScanOperator。否则将会把FilterOperator生成的合成谓词替换为常量谓词TRUE。

遇到符合条件的FilterOperator,动态分区剪裁优化会执行以下操作:

Hive 动态分区剪裁原理

1.     收集谓词中所有的动态分区条件的列(a in select b from other table),遍历所有的列并执行2、3。

2.     如果列是分区列,那么生成AppMasterEventOperator,从ReduceSinkOperator的节点开始,收集相关列的集合并将其发送给AppMaster。

3.     将Filter中动态分区谓词条件设置为TRUE

4.     将TableScanOperator动态分区谓词条件设置为TRUE。

随后的优化中会移除谓词为TRUE的filter和表达式。

3.2.2        依据统计量移除动态裁剪

这个优化会先遍历整个Operator树,找到AppMasterEventOperator,如果AppMasterEventOperator的统计数据大于hive.tez.dynamic.partition.pruning.max.data.size参数指定的大小,就会将本分支移除。

3.2.3        动态裁剪循环分析优化

该优化借助Tarjan算法计算图的所有强连通分量。在连通分量中保留处理数据量最小的AppMasterEventOperator.

3.3      Tez 生成task

在这一步,处理所有的AppMasterEventOperator,设置AppMasterEventDesc的目标顶点信息。在运行时,AppMasterEventOperator会将数据发送给设置的顶点。

4      Tez运行时分区剪裁

4.1      AppMasterEventOperator运行时发送分区数据

AppMasterEventOperator在运行时,将会把所有的数据存储到一个buffer中,如果发现数据大小超过了hive.tez.dynamic.partition.pruning.max.event.size指定的大小,那么会重新初始化buffer,只写入两个字段:列名和跳过分区,否则通过ProcessorContext将事件发送给AppMaster。

4.2      HiveSplitGenerator

HiveSplitGenerator用于Tez生成split,其在初始化时会等待事件输入(AppMasterEventOperator发送的事件),如果没有事件会直接跳过动态分区剪裁,如果存在事件,那么会等待所有的事件接收完毕,执行分区剪裁。生成的split中会去除不需要的分区。

5      参考文档

1.     https://issues.apache.org/jira/browse/HIVE-7826

2.     https://cwiki.apache.org/confluence/display/Hive/MapJoin+and+Partition+Pruning

大数据

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:「免费开源」基于Vue和Quasar的crudapi前端SPA项目实战之文件上传(十)
下一篇:JupyterNotebook‘s Magic
相关文章