Hive中Join导致的数据倾斜优化
未经优化的join操作默认是使用common join算法也就是通过一个MapReduce Job完成计算。Map端负责读取join操作所需表的数据并按照关联字段进行分区通过Shuffle将其发送到Reduce端相同key的数据在Reduce端完成最终的Join操作。如果关联字段的值分布不均就可能导致大量相同的key进入同一Reduce从而导致数据倾斜问题。由join导致的数据倾斜问题有如下三种解决方案1map join使用map join算法join操作仅在map端就能完成没有shuffle操作没有reduce阶段自然不会产生reduce端的数据倾斜。该方案适用于大表join小表时发生数据倾斜的场景。相关参数如下--启动Map Join自动转换 set hive.auto.convert.jointrue; --一个Common Join operator转为Map Join operator的判断条件,若该Common Join相关的表中,存在n-1张表的大小总和该值,则生成一个Map Join计划,此时可能存在多种n-1张表的组合均满足该条件,则hive会为每种满足条件的组合均生成一个Map Join计划,同时还会保留原有的Common Join计划作为后备(back up)计划,实际运行时,优先执行Map Join计划若不能执行成功则启动Common Join后备计划。 set hive.mapjoin.smalltable.filesize250000; --开启无条件转Map Join set hive.auto.convert.join.noconditionaltasktrue; --无条件转Map Join时的小表之和阈值,若一个Common Join operator相关的表中存在n-1张表的大小总和该值,此时hive便不会再为每种n-1张表的组合均生成Map Join计划,同时也不会保留Common Join作为后备计划。而是只生成一个最优的Map Join计划。 set hive.auto.convert.join.noconditionaltask.size10000000;2skew joinskew join的原理是为倾斜的大key单独启动一个map join任务进行计算其余key进行正常的common join。原理图如下相关参数如下--启用skew join优化 set hive.optimize.skewjointrue; --触发skew join的阈值若某个key的行数超过该参数值则触发 set hive.skewjoin.key100000;这种方案对参与join的源表大小没有要求但是对两表中倾斜的key的数据量有要求要求一张表中的倾斜key的数据量比较小方便走mapjoin。3调整SQL语句若参与join的两表均为大表其中一张表的数据是倾斜的此时也可通过以下方式对SQL语句进行相应的调整。假设原始SQL语句如下AB两表均为大表表A的数据是倾斜的。hive (default) select * from A join B on A.idB.id;图中1001为倾斜的大key可以看到其被发往了同一个Reduce进行处理。调整SQL语句如下hive (default) select * from( select --打散操作 concat(id,_,cast(rand()*2 as int)) id, value from A )ta join( select --扩容操作 concat(id,_,0) id, value from B union all select concat(id,_,1) id, value from B )tb on ta.idtb.id;数据变多了没事因为我们本来处理的就是大数据不怕数据量大就怕数据倾斜