第五章_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() }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界