spark数据倾斜解决方案汇总

什么是数据倾斜?
在shuffle操作的时候,是按照key来进行value的数据的输出,拉取和聚合的,同一个key的values,一定是分配到同一个reduce task进行处理的,假如对100w的数据做shuffle,其中98w的数据key是相同的,那么就会造成某个task执行98w数据聚合,而其他task很快执行完毕,整个shuffle操作都在等在这个task的执行,不仅大幅拉长了任务的执行时间,并且极易出现OOM。

数据倾斜如何发现?

无论client模式还是cluster模式,都可以在4040端口上查看各个task的执行细节,比如下图中(来源网络),倒数第三列显示了每个task的运行时间。明显可以看到,有的task运行特别快,只需要几秒钟就可以运行完;而有的task运行特别慢,需要几分钟才能运行完,此时单从运行时间上看就已经能够确定发生数据倾斜了。此外,倒数第一列显示了每个task处理的数据量,明显可以看到,运行时间特别短的task只需要处理几百KB的数据即可,而运行时间特别长的task需要处理几千KB的数据,处理的数据量差了10倍。此时更加能够确定是发生了数据倾斜。

数据倾斜解决方案:

1.repartition

这是最简单的解决办法,在发现数据倾斜的shuffle算子上,调用repartition方法,传入一个更大的并行度。

或者给shuffle算子传递进去一个参数,即一个数字,这个数字就代表了shuffle操作时reduce端的并行度。

2.使用随机key实现双重聚合

当然,这个场景主要用于reduceByKey,groupByKey,而非join。

如图所示:

原理: 
在第一轮聚合时,对key进行打散,将原先一样的key,变成不一样的key,相当于将每个key分组,然后针对key的多个分组,进行key的局部聚合,接着再去掉key的前缀,然后对所有key进行全局聚合,这种方案对解决这两个算子产生的数据倾斜有比较好的效果

3.reduce join转换为map join(join算子操作的数据倾斜解决方案)

如图所示,普通的join,肯定是要走shuffle,那么,既然走shuffle,那么普通的join肯定是reduce join, 即将所有相同的key对应的values,聚合到一个task中,再进行join操作 。
那么如何将reduce join转换为map join? 
当两个RDD要进行join时,其中一个RDD是比较小的,那么就可将该小数据量RDD广播出去,该RDD数据将会在每个executor的blockmanager中驻留一份数据,然后在map操作中就可以使用该数据,这种方式下,根本就不会发生shuffle操作,从而从根本上杜绝了数据倾斜。

4.sample采样倾斜key进行两次join

这个方案的实现思路关键之处在于: 
将发生数据倾斜的key单独拉出来,放到一个RDD中,然后用这个原本会产生数据倾斜的key RDD和其他RDD单独去join一下,这个时候,key对应的数据,可能就会分散到多个task中进行join操作。
,如果该倾斜key与其他key混合在一起中,肯定会导致这个key对应的所有数据都聚合到一个task中,然后导致数据倾斜 。

这是几种处理数据倾斜的通用方案,一般能够解决大部分数据倾斜的问题。当然本人没有贴代码讲解,默认你都大数据各种算子的操作有了一定的理解(其实也不难)。

如果有更好的解决数据倾斜的办法,欢迎指教。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值