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).cache()

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

3、运行效果&参考文章

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

  1. 解决spark中遇到的数据倾斜问题
  2. Spark Core中解决group by造成的数据倾斜问题
  3. Scala中sliding与grouped的区别
发布了31 篇原创文章 · 获赞 41 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/circle2015/article/details/105590003