《深入理解Spark》之通过自定义分区器解决数据倾斜问题

package com.lyzx.day37

import org.apache.spark.{Partitioner, SparkConf, SparkContext}

class D1 {

  //partitionBy和自定义分区器解决数据倾斜的问题
  def f1(sc:SparkContext): Unit ={
     val  r1 = sc.parallelize(1 to 100,4)
     val filterRdd = r1.filter(_ > 49)
      filterRdd.mapPartitionsWithIndex((idx,itr)=>{
        while(itr.hasNext){
          println("["+idx+"]"+itr.next())
        }
        for(v <- itr) yield  v
      }).collect()
    println(filterRdd.partitions.length)
    val reP = filterRdd
                .map(x=>(x,null))
                .partitionBy(new P(r1.partitions.length))
                  .map(x=>x._1)

    reP.mapPartitionsWithIndex((idx,itr)=>{
      while(itr.hasNext){
        println("["+idx+"]"+itr.next())
      }
      for(v <- itr) yield  v
    }).collect()
  }


  //只对K,V键值对的键做操作
  def f2(sc:SparkContext): Unit ={
    val  r1 = sc.parallelize(1 to 10).map(x=>(x,x))
    r1.mapValues(_+1)
      .foreach(println)
    println("====================================")

    //做完mapValues之后再压平 可以把一个值映射为一个集合
    //在压平的过程中把集合中的值掏出来,组合为(K1,V1),(K1,V2)的格式
    r1.flatMapValues(x=>Seq(x+100,x))
        .foreach(println)
  }


}

object D1{

  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("day36").setMaster("local")
    val sc = new SparkContext(conf)
    val t = new D1

//    t.f1(sc)
    t.f2(sc)
    sc.stop()
  }
}

//自定义分区器,把数据均匀的分配到各个Partition上
class P(num:Int) extends  Partitioner{
  private var N:Int = 0
  override def numPartitions: Int = num

  //这么做就和key没有关系,只是完全按照数据的个数把他们分配到各个Partition中
  override def getPartition(key: Any): Int = {
    val currentIndex = (N % num)
    N += 1
    N = N % num  //这样做是为了让N保持在0 - num-1 之间防止N超出long的范围
    currentIndex
  }
}
Spark中,数据倾斜是指某些分区的数据量过大或者数据分布不均匀,导致任务执行效率低下。以下是一些可以用来解决Spark数据倾斜问题的方法: 1. 增加分区数:通过增加RDD的分区数,可以将数据更均匀地分布到更多的节点上,减少单个节点处理的数据量。 2. 随机前缀:对于可能导致数据倾斜的key,可以在处理之前为其添加随机前缀,使得分发到不同分区的概率更加均匀。 3. Salting:对于可能导致数据倾斜的key,可以在处理之前为其添加随机字符串或者数字,将数据均匀分散到不同的分区。 4. 自定义分区器:通过自定义RDD的分区器,可以根据key进行更均匀的分区,避免某些key集中在一个分区中。 5. 聚合合并:对于发生数据倾斜的key,可以在Map阶段使用Combiner函数进行本地聚合,减少传输到Reducer节点的数据量。 6. Sample抽样:通过对输入数据进行抽样,可以更好地了解数据分布情况,有助于调整任务的配置和参数。 7. 均匀分配资源:确保集群中的资源(CPU、内存等)均匀分配给任务,避免某些节点负载过重而导致数据倾斜。 8. 重分区:通过对倾斜的RDD进行重分区操作,将数据均匀地分布到不同的分区中。 9. 前置处理:对于可能导致数据倾斜的操作,可以在之前添加预处理步骤,如聚合或过滤,减少倾斜的可能性。 以上方法可以用来解决Spark中的数据倾斜问题,具体选择哪种方法或者进行组合使用,需要根据具体情况和数据特征进行调整和优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值