当前位置:   article > 正文

Hive优化—skew join优化原理详解_hive skewjoin

hive skewjoin

目录

优化原理

​编辑适用范围

测试验证


优化原理

        JOIN中倾斜键的处理思路最早是在HIVE-964中提出的,整体思路是使用独立的作业和mapjoin来处理倾斜的键。

        用以处理倾斜键的MR作业数是表的数量减一(we can stream the last table, so big keys in the last table will not be a problem)

        在执行JOIN的过程中,会将一个表中的大key(也就是倾斜的那部分数据,判断是否倾斜由配置项hive.skewjoin.key指定,默认是100000)输出到一个对应的目录中,同时该key在其他表中的数据输出到其他的目录中(每个表一个目录)。整个目录结构类似下面这样:

  •  T1表中的大key存储在目录 dir-T1-bigkeys中,这些key在T2表的数据存储在dir-T2-keys中,这些key在T3表的数据存储在dir-T3-keys中,以此类推。。。
  • T2表中的大key在T1中的数据存储在 dir-T1-keys,T2表中的大key存储在目录dir-T2-bigkeys中,这些key在T3表的数据存储在dir-T3-keys中,以此类推。。。
  • T3表中的大key在T1中的数据存储在 dir-T1-keys,这些key在T2表的数据存储在dir-T2-keys中,T3表中的大key存储在目录dir-T3-bigkeys中,以此类推。。。

        对于每个表,都会单独启动一个mapjoin作业处理,输入的数据,就是该表的大key的目录和其他表中这些key对应的目录,对于上面情况基本就是会启动三个map join作业(一行对应一个)

        对于每个表中每一个倾斜键(skew key一个表中可能会有多个倾斜键)首先会写入到本地的一个临时文件中,最后将这些文件上传到HDFS中。

下面是一张在网上找到的图片,可以帮助我们理解优化过程

在这里插入图片描述
适用范围

         Hive包含有INNER JOIN,UNION JOIN,LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN等多种JOIN类型,那么这些JOIN都能够适用skew join优化吗?

        在Hive中,用于处理skew join的类主要有GenMRSkewJoinProcessor和GenSparkSkewJoinProcessor,他们都在org.apache.hadoop.hive.ql.optimizer.physical package中,从名字上就可以看出他们分别用以MR和Spark引擎,事实上GenSparkSkewJoinProcessor是直接拷贝的GenMRSkewJoinProcessor,因此二者逻辑上完全一样。

        在这两个类中,是否能够使用skew join优化,是有条件中,如果不满足条件,是无法使用skew join 优化特性的。如下代码截图,可以看到这里调用GenMRSkewJoinProcessor.skewJoinEnabled()来判断是否能够使用优化。

在这里插入图片描述

 看一下GenMRSkewJoinProcessor.skewJoinEnabled方法的实现:

在这里插入图片描述

 从上面的代码中,可以看到要使用skew join优化,必须满足如下的条件:

  • 开启优化特性,也就是hive.optimize.skewjoin配置项必须是true,默认是false,这一点想必都很熟悉了。
  • 不能是outer join,这里只是简单的说outer join 不能使用倾斜优化,那么这些outer join 具体包括哪些呢?

继续查看源码后最终发现这个值的设置是通过QBJoinTree.setNoOuterJoin()方法完成的,进一步发现在SemanticAnalyzer类中多次调用了这个方法,并且将这个值设置为false。

在这里插入图片描述

在这里插入图片描述

到这里就可以知道在Hive中,UNION JOIN,LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN 这几种join是无法使用skew join优化的。只有INNER JOIN才可以!

测试验证

在开启倾斜优化后,会在task(hive on spark)中看到如下的日志信息:

在这里插入图片描述

上面的日志说明,hive对这些超过了hive.skewjoin.key配置项指定阈值的key从本地拷贝到了一个HDFS目录中,这一点和文章开头的分析一致

然后看一下,对应的HDFS目录中的结构,可以看到两张表的数据,大表的数据会划分到了多个目录中,另一张较小的表的目录结构与大表的目录结构一致

在这里插入图片描述

小表中每个子目录中数据是完全一样的

在这里插入图片描述

 另外从task的执行日志可以看到其使用了skewjoin优化

在这里插入图片描述


————————————————
版权声明:本文为CSDN博主「看得出的就是」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CPP_MAYIBO/article/details/111350138

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号