第五章_Spark核心编程_Rdd_转换算子_Value型_coalesce算子

 


1. 说明

复制代码
/*
 * 1. 定义
 *   def coalesce(numPartitions: Int
 *              , shuffle: Boolean = false
 *              , partitionCoalescer: Option[PartitionCoalescer] = Option.empty)
 *                (implicit ord: Ordering[T] = null)
 *        : RDD[T]
 *    numPartitions : 指定分区个数
 *    shuffle : 是否需要shuffle(默认为false)
 *
 * 2. 功能
 *       调整Rdd的分区个数(变大\变小),改变分区时,可以选择是否Shuffle
* shffle=true,分区可以变大或者变小
* shuffle=false,分区是能变小(变大不生效) * * 3. note * 1.不shuffle 即 shuffle = false * 分区数变大时,如父rdd 10分区,子rdd 100分区 * 通过 rdd.coalesce(100) 处理后,子rdd分区数已然是10,不会变大 * 分区数变小时,如父rdd 1000分区,子rdd 100分区 * 通过 rdd.coalesce(100),子rdd 会合并 * * 2.shuffle 即 shuffle = true * 无论分区变大还是变小,数据都会被分配到每个分区 * * 4. 使用场景 * 当spark任务中分区数过多时(即每个Task处理数据量不大),此时存在过多的小任务,Task的启动和调度都会 * 消耗时间,此时可以对分区进行合并,来减少Task的数量,从而减小任务调度的开销 * *
*/
复制代码
复制代码
/* coalesce 算子 */
object RddTransitionOperator_coalesce extends App {
  private val sc: SparkContext = CommonUtils.getSparkContext("groupBy distinct")

  private val rdd: RDD[Long] = sc.range(1, 10, 1, 4)

  private val rdd2: RDD[Long] = rdd.coalesce(5, false)

  println(s"分区数:${rdd2.getNumPartitions}")
  println(s"rdd类型:${rdd2.getClass.getName}")
  //  分区数:2
  //  rdd类型:org.apache.spark.rdd.CoalescedRDD

  rdd2.collect().foreach(println(_))
  rdd2.saveAsTextFile("src/main/data/output/listrdd9")


  private val rdd3: RDD[Long] = rdd.coalesce(6, true)
  println(s"分区数:${rdd3.getNumPartitions}")
  println(s"rdd类型:${rdd3.getClass.getName}")
  //  分区数:2
  //  rdd类型:org.apache.spark.rdd.MapPartitionsRDD

  //rdd3.collect()
  //rdd3.saveAsTextFile("src/main/data/output/listrdd7")

  //sc.stop()
  while (true) {}
}
复制代码

 2. 缩小(合并)分区

复制代码
  object coalesceTest extends App {
    //缩小(合并)分区
    /*
    *  1. shuffle Vs No Shuffle
    *        shuffle : 会使用分区器,对元素重新分区,均衡的分发到分区内
    *     No Shuffle : 只是 简单的对某几个分区进行 合并操作(可能造成 数据倾斜)
    *
    *  2. note
    *     合并分区时,尽量shuffle
    *
    *  3. 示例-No Shuffle
    *     rdd
    *        part-00000 : 1, 2, 3
    *        part-00001 : 4, 5, 6
    *        part-00002 : 7, 8, 9
    *     rdd1(数据分布不均)
    *        part-00000 : 1, 2, 3
    *        part-00001 : 4, 5, 6, 7, 8, 9
    *
    *  3. 示例-Shuffle
    *     rdd
    *        part-00000 : 1, 2, 3
    *        part-00001 : 4, 5, 6
    *        part-00002 : 7, 8, 9
    *     rdd1(数据分布均衡)
    *        part-00000 : 1, 3, 5, 7, 9
    *        part-00001 : 2, 4, 6, 8
    *
    * */

    val sparkconf: SparkConf = new SparkConf().setMaster("local").setAppName("distinctTest")

    val sc: SparkContext = new SparkContext(sparkconf)

    val rdd = sc.makeRDD(List(1, 2, 3, 4, 5, 6, 7, 8, 9), 3)

    //rdd.saveAsTextFile("Spark_319/src/output/01")

    private val rdd1: RDD[Int] = rdd.coalesce(2,true)

    rdd1.saveAsTextFile("Spark_319/src/output/02")


    println(s"当前分区数 : ${rdd1.getNumPartitions}")

    println(rdd1.collect().mkString(","))

    sc.stop()

  }
复制代码

3. 扩大分区

复制代码
  object coalesceTest extends App {
    //扩大分区
    /*
    *  1. shuffle Vs No Shuffle
    *        shuffle : 会使用分区器,对元素重新分区,均衡的分发到分区内
    *     No Shuffle : 不会生效
    *
    *  2. note
    *     扩大分区时,如果不shuflle,将不会生效
    *     coalesce(numPartitions, shuffle = true) = repartition(numPartitions)
    *
    * */

    val sparkconf: SparkConf = new SparkConf().setMaster("local").setAppName("distinctTest")

    val sc: SparkContext = new SparkContext(sparkconf)

    val rdd = sc.makeRDD(List(1, 2, 3, 4, 5, 6, 7, 8, 9), 1)

    //rdd.saveAsTextFile("Spark_319/src/output/01")

    private val rdd1: RDD[Int] = rdd.coalesce(2, true)

    private val rdd2: RDD[Int] = rdd.repartition(2)

    rdd1.saveAsTextFile("Spark_319/src/output/02")
    rdd1.saveAsTextFile("Spark_319/src/output/03")

    println(s"当前分区数 : ${rdd1.getNumPartitions}")

    println(rdd1.collect().mkString(","))

    sc.stop()

  }
复制代码

 

posted @   学而不思则罔!  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示