数仓(Hive)数据倾斜产生原因及处理方式

参考资料:B站@左美美_ 相关视频

数据倾斜定义

 任务进度长时间维持在99%,查看任务监异页面,发现只有少量1个或几个reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多,最长时长远大于平均时长。

数据倾斜产生原因

 map输出数据按keyHash的分配到reduce中,由于key分布不均匀、业务数据本身的特性、建表时考虑不周、某些SQL语句本身就有数据倾斜等原因,造成的reduce上的数据量差异过大,所以如何将数据均匀的分配到各个reduce中,就是解决数据倾斜的根本所在。

Key为空引起数据倾斜

倾斜原因

join的key值发生倾斜,key值包含很多空值或是异常值。

解决方案

对值为空的key进行打散,为空key赋一个随机的值,使得key值为空的数据随机均匀地分布到不同的reducer上。

测试案例

设置多个reduce任务

set mapreduce.job.reduces = 5;

两张大表join,做全连接

1
2
3
4
5
6
7
select t.id
       ,t.year
       ,t.temperature
       ,s.state
  from temperature t 
    full join station s on nvl(t.id,rand())=s.id
  limit 10;

备注:nvl()为空值转换函数,rand()为随机函数。也可以使用ifnull()coalesce()

group by 引起数据倾斜

倾斜原因

默认情况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了。

解决方案

并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合,最后在Reduce端得出最终结果。

实现方式1

1)是否在Map端进行聚合,默认为True(使用Combiner局部合并)

set hive.map.aggr = true;

2)设置map端预聚合的行数阈值

set hive.groupby.mapaggr.checkinterval=100000;

实现方式2

有数据倾斜的时候进行负载均衡(默认是false)

set hive.groupby.skelindata= true;

 当遇到数据倾斜时,groupby会启动两个MR job。第一个job会将map端数据随机输入reducer,每个reducer做部分聚合,相同的key就会分布在不同的reducer中。第二个job再将前面预处理过的数据按key聚合并输出结果,这样就起到了均衡的效果。

测试案例

1
2
3
set hive.map.aggr =true;
set hive.groupby.mapaggr.checkinterval= 100000;
set hive.groupby.skewindata= true;
1
2
3
select id,count(*)
  from temperature 
  group by id;

count distinct引起数据倾斜

倾斜原因

count distinct聚合时存在大量特殊值,比如存在大量值为NULL或空的记录。

解决方案

做count distinct时,将值为空的情况单独处理。

1)如果只是统计去重后的记录数,可以不用处理空值,先把空值过滤掉,然后在最后结果中加1即可

2)如果还包含其他计算,需要进行groupby操作,先将值为空的记录单独处理,然后再跟其他计算结果union操作。

join操作引起数据倾斜

大表join小表(hive旧版本)

新版本(Hive3)已经自动自动优化

1)产生原因

业务数据本身就存在key分布不均匀的情况,一般情况会产生数据倾斜

2)解决方式

使用map join让小的维度表先进内存,在map端完成join

3)实现原理

使用map join,直接在map端就完成表的join操作,进入map端的数据都是经过split得到的,没有根据key分区这一操作,所以数据都是相对均匀地分布在每个maptask中的,所以就不会产生数据倾斜。

大表join大表

1)产生原因

业务数据本身的特性,导致两个表都是大表。

2)解决方式

业务消减

3)实现原理

 业务数据有数据倾斜的风险,但是这些导致数据倾斜风险的key一般都是无效的,如uid为空,因为uid为空的记录是没有意义的。

 所以当业务数据很大,但是数据中的大部分(一般都是80%)可能都是无效数据,那么就可以在join时过滤掉空值uid,没有了这些无效数据,自然就不存在这么大量集中的key,数据倾斜的风险就会消失。

网站总访客数:Loading
网站总访问量:Loading
使用 Hugo 构建
主题 StackJimmy 设计