赞
踩
目录
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在其他表中的数据输出到其他的目录中(每个表一个目录)。整个目录结构类似下面这样:
对于每个表,都会单独启动一个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优化,必须满足如下的条件:
继续查看源码后最终发现这个值的设置是通过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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。