数据倾斜

384 阅读4分钟

前言:在分布式大数据处理领域,会把一份比较大的数据分成若干份小的数据放在集群的不同机器上去并行处理,这可以理解为分区操作。而数据倾斜是不陌生的,即使是正常的数据分布,理论上也是会出现数据倾斜情况的,不管是hive还是spark处理数据,都可能会出现数据倾斜的情况,当然数据倾斜也是可通过一些方式来规避的。

一、什么是数据倾斜

大批数据量处理然后分区不均衡的情况下就会造成集群某台机器超负荷工作,而某台机器却零负荷,即运作分配不均衡,忙的忙死,闲的闲死,这就是数据倾斜的情况,主要是数据的key分配严重不均。数据倾斜情况的很大表现是:部分task执行的很快,剩下几个task执行得特别慢。减少数据量就能一定程度减少数据倾斜的风险,做数据收敛处理。

先来认识一条公式:(key.hashCode()&Integer.MAX_VALUE)%numReduceTasks ,这条公式是在MapReduce场景下计算数据处理分区的,从公式可看出,如果key的hash值重复了,即存在大量的相同key,mapper阶段后是通过分区来决定reduce阶段执行情况的,相同key的数据分到同一个分区去处理,那假设100w数据,有90w的数据key是相同的,剩下的10w分成1个机器去执行,再假设处理10w数据需要1分钟,那么第二台机器用了1分钟处理完,而第一台机器则要用9分钟执行,这么看数据处理结果至少得9分钟才能跑出来,从并行处理的层面看这就没有多大效率,其实友好的情况是key相对分散,不会导致大部分都集中在一起,100w数据分成大概几个key,分到不同的分区并行处理,处理时长都差不多,这样各机器并行处理的时间耗时就差不多同时完成,不会存在最终数据结果一直卡在某个reduce过程中。

数据倾斜三种形式:

  • 分区不均,某几个分区对应的key太多,多数情况是这种倾斜
  • 单个key对应的数据量太多
  • 单条记录数据太大(比如数组中值太多)

二、解决hive数据倾斜

解决数据倾斜没有固定的方法,具体得根据业务自定义partitioner的实现,不同场景不同的应对方案。分为map端倾斜还是reduce端倾斜,map倾斜主要是因为输入文件大小不均匀导致,reduce端倾斜主要是partition不均匀导致。

  • 1、考虑是否map端缓慢,输入数据文件多,大小不均匀

如果小文件过多,每个小文件都启动一个map任务,导致map任务启动和初始化时间大于逻辑处理数据的时间,从而资源浪费甚至OOM,所以当启动一个任务后,发现数据量小但任务数量多时,可以在map端先进行输入合并,命令的话在下面自行选取。

set hive.merge.mapfiles=true      //设置在map端输出时合并小文件
set hive.merge.mapredfiles=true   //设置在reduce端输出时合并小文件
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat     //执行map前进行小文件自动合并
set hive.groupby.skewindata=true (默认关闭状态)      //设置有数据倾斜时自动进行负载均衡,生成的执行计划会有两个MR job
set mapred.map.tasks和set mapred.reduce.tasks    //这两个命令是分别用来增加map个数和reduce个数的

单个文件大小稍稍大于配置的block块大小时,需要增加map个数,如果文件大小适中,但map端计算量非常大,则需要增加reduce个数。

  • 2、考虑是否大表对小表关联

大表join小表时,记得把小表放左侧,大表放右侧,或者使用mapjoin写法把小表加载到内存中

select /*+mapjoin(a)*/ a.c1,b.c1
from a join b
where a.c1=b.c1
  • 3、考虑是否关联字段有null值

当关联字段有null值的数据时,null值的reduce都会落到一个节点上执行。

解决方法:要么关联前把字段的null值过滤掉,null值的数据不参与关联;要么就使用case when给空值分配随机的key(字符串+rand())

  • 4、考虑关联字段的数据类型是否一致

多注意数值类型与字符串类型的数据

  • 5、考虑是否有count(distinct)计算去重的指标

当数据量非常大时,count(distinct)是会出现数据倾斜的情况的,可以通过改造hiveQL写法来解决

select a,count(distinct b) 
from c 
group by a

-->改造后

select a,sum(1) 
from 
    (select a,b 
    from c 
    group by a,b
    ) s
group by a

附:参考学习文章

1、hive数据倾斜解决方案:www.cnblogs.com/wangbin2188…

2、hive数据倾斜优化方案:blog.csdn.net/qq_35036995…

3、面试必问之数据倾斜:zhuanlan.zhihu.com/p/64240857

4、数据倾斜处理:www.jianshu.com/p/3635cd26b…