Hive中的数据倾斜优化
数据倾斜
- 一.概述
- 何为数据倾斜
- 导致的问题
- 二.优化
- group by 数据倾斜
- join 数据倾斜
一.概述
何为数据倾斜
运行的过程当中,有多个Reduce,每个Reduce拿到的数据不均匀,其中有一个或几个拿到的数据远远大于其他reduce拿到的数量,此时任务出现了数据倾斜;
导致的问题
- 执行效率下降(整个reduce时间,就看最后一个reduce结束时间);
- 由于reduce长时间运行不完,导致资源长期被占用,一旦超时,YARN会强制回收资源,导致运行失败
- 导致节点宕机;
二.优化
group by 数据倾斜
-
方案一:Combiner预聚合
一个MR,在【每一个MapTask】使用Combiner预聚合,将聚合之后的结果发往Reduce,这样在Reduce接收到的数据就少了,从而解决数据倾斜;配置:
开启map端提前聚合 ; -
方案二: 负载均衡(大Combiner) skew
采用两个MR来解决,
第一次MR负责将数据均匀落在不同的reduce上进行聚合统计,形成一个局部的结果;
第二个MR,读取第一个MR的局部结果,按照相同的key发往同一个reduce,完成统计;配置:
注意:
当使用负载均衡时间,不支持在多列上去重,会报错;
join 数据倾斜
-
方案一: Map join、Bucket map join、 SMB map join
将ruduce端的join操作移到到【MapTask的内存】,直接将倾斜排除,因为map一般不会有数据倾斜问题,map是根据切片来读取文件,切片block(128mb) 是均匀切的;但是三种map join都需要满足相关条件,如分桶的数量要整数倍/相同,分桶字段相同;但是很多时候不满足这些条件!
注意:在map join之前,还有两个通用方法:
①筛选掉无用字段
②null值太多时将其随机赋值打散,以免数据倾斜; -
方案二: 在Reduce端解决(无条件) skew join
建议开启 union优化,以减少二次读写,减少union输出的额外扫描;整体效率更高;思路:
将容易产生倾斜的key的值从整个环境中排除掉,将倾斜的数据单独找一个MR来处理,,算完后返回结果;
如何知道哪个值导致的倾斜?
①编译(建表)期解决 (明确知道key值的倾斜问题时)
明确知道key值有倾斜问题,一般采用编译器解决,在建表的时候,提前设置好对应值有倾斜即可,执行时,hive会将这些倾斜的key从这个MR排除,单独找一个MR来处理; 最后底层用union all合并;
②运行期解决**(当不知道哪个key导致倾斜时,设定阀值,动态检测)
执行时,hive会记录每个key出现的次数,当key的次数达到特定的阀值,就认为key导致数据倾斜,将key的数据排除掉,单独用MR去处理;最后底层用union all合并;
一般设置阀值为平均key个数的3~10倍,认为会产生数据倾斜;