spark数据倾斜问题总结

一、数据倾斜介绍与定位

a、数据倾斜的现象,有两种表现:

1、某个task一直在执行任务,其他task轻松执行任务马上就结束了。
2、有的task正常运行,有的task内存泄漏。

c、数据倾斜定位与出现问题的位置:

根据log去定位

出现数据倾斜的原因,基本只可能是因为发生了shuffle操作,在shuffle的过程中,出现了数据倾斜的问题。因为某个,或者某些key对应的数据,远远的高于其他的key。

1、你在自己的程序里面找找,哪些地方用了会产生shuffle的算子,groupByKey、countByKey、reduceByKey、join

2.根绝内存溢出的stage,定位对应的shuffle:log一般会报是在你的哪一行代码,导致了OOM异常;或者呢,看log,看看是执行到了第几个stage!!!哪一个stage,task特别慢,就能够自己用肉眼去对你的spark代码进行stage的划分,就能够通过stage定位到你的代码,哪里发生了数据倾斜。去找找,代码那个地方,是哪个shuffle操作。

二、解决方法一:聚合数据源

聚合数据源做法一:

数据倾斜,某个key对应的80万个属性,某些key对应几百条属性,某些key对应几十条属性;现在,咱们直接在生成hive表的hive etl中,对数据进行聚合。比如按key来分组,将key对应的所有的values,全部用一种特殊的格式,拼接到一个字符串里面去,比如“key=sessionid, value: action_seq=1|user_id=1|search_keyword….”。

对key进行group,在spark中,拿到key=sessionid,values;hive etl中,直接对key进行了聚合。那么也就意味着,每个key就只对应一条数据。在spark中,就不需要再去执行groupByKey+map这种操作了。直接对每个key对应的values字符串,map操作,进行你需要的操作即可。key,values串。spark中,可能对这个操作,就不需要执行shffule操作了,也就根本不可能导致数据倾斜。

或者是,对每个key在hive etl中进行聚合,对所有values聚合一下,不一定是拼接起来,可能是直接进行计算。reduceByKey,计算函数,应用在hive etl中,每个key的values。

数据从三条数据:
<sessionid,action_seq>
<ssessionid,user_id>
<sessionid,search_keyword>
在ETL中变成了:
<sessionid,action_seq+user_id+search_keyword>

聚合数据源做法二:

你可能没有办法对每个key,就聚合出来一条数据;

那么也可以做一个妥协;对每个key对应的数据,10万条;有好几个粒度,比如10万条里面包含了几个城市、几天、几个地区的数据,现在放粗粒度;直接就按照城市粒度,做一下聚合,几个城市,几天、几个地区粒度的数据,都给聚合起来。比如说

city_id,date,area_id
select … from … group by city_id,date,area_id
一个key的三条属性city_id,date,area_id,变成了一条属性city_id+date+area_id
尽量去聚合,减少每个key对应的数量,也许聚合到比较粗的粒度之后,原先有10万数据量的key,现在只有1万数据量。减轻数据倾斜的现象和问题。

方法一和方法二是类似的

三、解决方法二:提高shuffle操作reduce并行度

如果第一种方法不适合做。那么采用第二种方法:提高shuffle操作的reduce并行度 将增加reduce task的数量,就可以让每个reduce task分配到更少的数据量,这样的话,也许就可以缓解,或者甚至是基本解决掉数据倾斜的问题。

四、解决方法之三:随机key实现双重聚合

使用场景:(1)groupByKey(2)reduceByKey
join,咱们通常不会这样来做,后面有针对不同的join造成的数据倾斜的问题的解决方案。

就是将不同的key拆分:
key1,key2,…
变成了
key1_1,key1_2,key1_3,key2_1,key2_2,key2_3,key2_4,…
在这里插入图片描述

五:map jion转化为reduce jion

原本是在map操作+reduce操作,我们变成了map操作+map操作
在这里插入图片描述
这种方式下,根本不会发生shuffle操作,肯定也不会发生数据倾斜;从根本上杜绝了join操作可能导致的数据倾斜的问题;对于join中有数据倾斜的情况,大家尽量第一时间先考虑这种方式,效果非常好;如果某个RDD比较小的情况下。

六:将会产生倾斜的RDD单独出来jion

在这里插入图片描述
其实关键之处在于,将发生数据倾斜的key,单独拉出来,放到一个RDD中去;就用这个原本会倾斜的key RDD跟其他RDD,单独去join一下,这个时候,key对应的数据,可能就会分散到多个task中去进行join操作(单独使用一个mapreduce,会再次shuffle一次)。

就不至于说是,这个key跟之前其他的key混合在一个RDD中时,肯定是会导致一个key对应的所有数据,都到一个task中去,就会导致数据倾斜。

七、解决方法之六:使用随机数以及扩容表进行join

在这里插入图片描述
步骤:

1、选择一个RDD,要用flatMap,进行扩容,将每条数据,映射为多条数据,每个映射出来的数据,都带了一个n以内的随机数,通常来说,会选择10。

2、将另外一个RDD,做普通的map映射操作,每条数据,都打上一个10以内的随机数。

3、最后,将两个处理后的RDD,进行join操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值