Spark数据倾斜问题解决与如何对pairRDD内部采样

1、问题背景

最近遇到一个这样的需求,需要将原始数据按照key进行汇总,然后把对应key的value数据按照时间排序进行排序,最后分别对每个key进行相同的value操作,于是遇到了严重的数据倾斜问题。

单个task接收到了单个key对应的大量value数据,造成处理耗时甚至OOM内存溢出或不足,使得整个任务被拖累。

2、数据倾斜解决方案

2.1、初步切分数据

由于需求的特殊性,key对应的value排序后可以进行sliding滑动选取操作,所以最初的单个(key, value)可以通过flatMapValues变成
(key0, value0)
(key0, value1)
(key0, value2)
(key0, value…)
(key0, valueN)

注意:该数据在进行mapValues操作时,key相同的value仍然被收集到同一个task上,所以仍然造成数据倾斜

    val originData:RDD[(String, List[String])] = ....
    val data = originData.flatMapValues( value => 
               value.map(x => (x, x.split("###")(3).toInt)).sortBy(_._2).map(_._1).grouped(1000))

上面的x.split("###")(3).toInt为我的取时间戳字段,grouped(1000)等于sliding(1000, 1000)

2.2、对所有key添加随机前缀

将原始的 key 转化为 key + 随机值(例如Random.nextInt)是一种常用方法

val dataShuffle = data.map(x => {
      val prifix = new Random().nextInt(100000)
      (prifix + "###" + x._1, x._2)
    }).repartition(100)

可以看到上面代码在key前面随机加上了一个10000以内的数字
注意.repartition(100)操作,该操作是为了在后续进行mapValues时,能够将数据均衡发送到每个task上面,也就是100个task

3、运行效果&参考文章

上述优化效果将代码执行时间从小时级别降低到分钟级别

  1. 解决spark中遇到的数据倾斜问题
  2. Spark Core中解决group by造成的数据倾斜问题
  3. Scala中sliding与grouped的区别
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值