大数据Spark(七十二):Transformation转换算子repartition和coalesce使用案例

文章目录

Transformation转换算子Repartition和Coalesce使用案例

一、Repartition使用案例

二、Coalesce使用案例


Transformation转换算子Repartition和Coalesce使用案例

一、Repartition使用案例

repartition可以对RDD进行重新分区,可以增加或减少分区,这个过程会产生shuffle,常用于对RDD进行增加分区,提高并行度场景。

注意:在底层,repartition(numPartitions) = coalesce(numPartitions,true)。

Java代码:

java 复制代码
SparkConf conf = new SparkConf().setMaster("local").setAppName("repartitionTest");
JavaSparkContext sc = new JavaSparkContext(conf);

JavaRDD<String> rdd1 = sc.parallelize(Arrays.asList(
        "love1", "love2", "love3", "love4",
        "love5", "love6", "love7", "love8",
        "love9", "love10", "love11", "love12"
), 3);

JavaRDD<String> rdd2 = rdd1.mapPartitionsWithIndex(new Function2<Integer, Iterator<String>, Iterator<String>>() {
    //index: 分区的索引,从0开始
    //iter: 分区中的元素
    @Override
    public Iterator<String> call(Integer index, Iterator<String> iter) throws Exception {
        ArrayList<String> list = new ArrayList<>();
        while (iter.hasNext()) {
            String next = iter.next();
            list.add("rdd1 partition index: " + index + " current value: " + next);
        }
        return list.iterator();
    }
}, true);

//对rdd2 进行重新分区
//JavaRDD<String> rdd3 = rdd2.repartition(4); //增加分区
JavaRDD<String> rdd3 = rdd2.repartition(2);//减少分区

JavaRDD<String> rdd4 = rdd3.mapPartitionsWithIndex(new Function2<Integer, Iterator<String>, Iterator<String>>() {
    //index: 分区的索引,从0开始
    //iter: 分区中的元素
    @Override
    public Iterator<String> call(Integer index, Iterator<String> iter) throws Exception {
        ArrayList<String> list = new ArrayList<>();
        while (iter.hasNext()) {
            String next = iter.next();
            list.add("rdd3 partition index: 【" + index + "】,current value: 【" + next + "】");
        }
        return list.iterator();
    }
}, true);

List<String> result = rdd4.collect();
for (String s : result) {
    System.out.println(s);
}

sc.stop();

Scala代码:

Scala 复制代码
val conf: SparkConf = new SparkConf().setMaster("local").setAppName("RepartitionTest")
val sc = new SparkContext(conf)

val rdd1: RDD[String] = sc.parallelize(List(
  "love1", "love2", "love3", "love4",
  "love5", "love6", "love7", "love8",
  "love9", "love10", "love11", "love12"
), 3)

val rdd2: RDD[String] = rdd1.mapPartitionsWithIndex((index, iter) => {
  val list = new ListBuffer[String]()
  while (iter.hasNext) {
    list.append(s"rdd1 partition index: $index ,current value: ${iter.next()}")
  }
  list.iterator
})

//对rdd2进行重分区
val rdd3: RDD[String] = rdd2.repartition(4) //增加分区
//val rdd3: RDD[String] = rdd2.repartition(2) //减少分区

val rdd4: RDD[String] = rdd3.mapPartitionsWithIndex((index, iter) => {
  val list = new ListBuffer[String]()
  while (iter.hasNext) {
    list.append(s"rdd3 partition index: 【$index】 ,current value: 【${iter.next()}】")
  }
  list.iterator
})

rdd4.collect.foreach(println)

sc.stop()

Java和Scala API结果如下,可见通过repartition进行增加或者减少分区操作会产生shuffle操作。

bash 复制代码
#repartition(4)结果
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love4】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 1 current value: love8】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 2 current value: love9】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 0 current value: love1】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love5】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love10】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 0 current value: love2】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 1 current value: love6】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 2 current value: love11】
rdd3 partition index: 【3】,current value: 【rdd1 partition index: 0 current value: love3】
rdd3 partition index: 【3】,current value: 【rdd1 partition index: 1 current value: love7】
rdd3 partition index: 【3】,current value: 【rdd1 partition index: 2 current value: love12】

#repartition(2)结果
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love2】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love4】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 1 current value: love6】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 1 current value: love8】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 2 current value: love9】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 2 current value: love11】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 0 current value: love1】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 0 current value: love3】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love5】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love7】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love10】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love12】

二、Coalesce使用案例

coalesce也可以对RDD分区增加或者减少,常用于减少RDD的分区数量,常用于提高小数据集的执行效率。与 repartition 不同,coalesce 默认情况下不会触发 Shuffle 操作,因此在减少分区时更加高效。函数签名如下:

Scala 复制代码
def coalesce(numPartitions: Int, shuffle: Boolean = false): RDD[T]

其中,numPartitions 表示目标分区数,shuffle 参数指示是否进行 Shuffle,默认为 false。

特别注意:如果coalesce设置的分区数比原来的RDD的分区数还多的话,第二个参数设置为false不会起作用,如果设置成true,效果和repartition一样。即repartition(numPartitions) = coalesce(numPartitions,true)。

Java代码:

java 复制代码
SparkConf conf = new SparkConf().setMaster("local").setAppName("CoalesceTest");
JavaSparkContext sc = new JavaSparkContext(conf);

JavaRDD<String> rdd1 = sc.parallelize(Arrays.asList(
        "love1", "love2", "love3", "love4",
        "love5", "love6", "love7", "love8",
        "love9", "love10", "love11", "love12"
), 3);

JavaRDD<String> rdd2 = rdd1.mapPartitionsWithIndex(new Function2<Integer, Iterator<String>, Iterator<String>>() {
    //index: 分区的索引,从0开始
    //iter: 分区中的元素
    @Override
    public Iterator<String> call(Integer index, Iterator<String> iter) throws Exception {
        ArrayList<String> list = new ArrayList<>();
        while (iter.hasNext()) {
            String next = iter.next();
            list.add("rdd1 partition index: " + index + " current value: " + next);
        }
        return list.iterator();
    }
}, true);

//coalesce对rdd2 进行重新分区,没有shuffle
//JavaRDD<String> rdd3 = rdd2.coalesce(2);
//JavaRDD<String> rdd3 = rdd2.coalesce(2,true);
JavaRDD<String> rdd3 = rdd2.coalesce(4,false);

JavaRDD<String> rdd4 = rdd3.mapPartitionsWithIndex(new Function2<Integer, Iterator<String>, Iterator<String>>() {
    //index: 分区的索引,从0开始
    //iter: 分区中的元素
    @Override
    public Iterator<String> call(Integer index, Iterator<String> iter) throws Exception {
        ArrayList<String> list = new ArrayList<>();
        while (iter.hasNext()) {
            String next = iter.next();
            list.add("rdd3 partition index: 【" + index + "】,current value: 【" + next + "】");
        }
        return list.iterator();
    }
}, true);

List<String> result = rdd4.collect();
for (String s : result) {
    System.out.println(s);
}

sc.stop();

Scala代码:

Scala 复制代码
val conf: SparkConf = new SparkConf().setMaster("local").setAppName("CoalesceTest")
val sc = new SparkContext(conf)

val rdd1: RDD[String] = sc.parallelize(List(
  "love1", "love2", "love3", "love4",
  "love5", "love6", "love7", "love8",
  "love9", "love10", "love11", "love12"
), 3)

val rdd2: RDD[String] = rdd1.mapPartitionsWithIndex((index, iter) => {
  val list = new ListBuffer[String]()
  while (iter.hasNext) {
    list.append(s"rdd1 partition index: $index ,current value: ${iter.next()}")
  }
  list.iterator
})

//coalesce对rdd2进行重分区,不产生shuffle
//val rdd3: RDD[String] = rdd2.coalesce(2)
//val rdd3: RDD[String] = rdd2.coalesce(2,true)
val rdd3: RDD[String] = rdd2.coalesce(4)

val rdd4: RDD[String] = rdd3.mapPartitionsWithIndex((index, iter) => {
  val list = new ListBuffer[String]()
  while (iter.hasNext) {
    list.append(s"rdd3 partition index: 【$index】 ,current value: 【${iter.next()}】")
  }
  list.iterator
})

rdd4.collect.foreach(println)

sc.stop()

Java和Scala API结果如下:

bash 复制代码
#coalesce(2)
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love1】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love2】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love3】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love4】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love5】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love6】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love7】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love8】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love9】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love10】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love11】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love12】

#coalesce(2,true),等同于repartition(2)
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love2】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love4】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 1 current value: love6】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 1 current value: love8】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 2 current value: love9】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 2 current value: love11】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 0 current value: love1】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 0 current value: love3】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love5】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love7】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love10】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 2 current value: love12】

#coalesce(4,false) 不起作用
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love1】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love2】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love3】
rdd3 partition index: 【0】,current value: 【rdd1 partition index: 0 current value: love4】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love5】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love6】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love7】
rdd3 partition index: 【1】,current value: 【rdd1 partition index: 1 current value: love8】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 2 current value: love9】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 2 current value: love10】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 2 current value: love11】
rdd3 partition index: 【2】,current value: 【rdd1 partition index: 2 current value: love12】

  • 📢博客主页:https://lansonli.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 Lansonli 原创,首发于 CSDN博客🙉
  • 📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨
相关推荐
深蓝电商API5 小时前
分布式事务在跨境交易中的解决方案
分布式·跨境电商·代购系统·反向海淘·代购平台·跨境代购
藦卡机器人5 小时前
中国工业机器人发展现状
大数据·人工智能·机器人
Simon_lca6 小时前
突破合规瓶颈:ZDHC Supplier to Zero(工厂零排放 - 进阶型)体系全攻略
大数据·网络·人工智能·分类·数据挖掘·数据分析·零售
黄焖鸡能干四碗8 小时前
网络安全建设实施方案(Word文件参考下载)
大数据·网络·人工智能·安全·web安全·制造
云境筑桃源哇9 小时前
马踏春风 为爱启航 | 瑞派宠物医院(南部新城旗舰店)盛大开业!打造宠物医疗新标杆!
大数据·宠物
我真会写代码9 小时前
从入门到精通:Kafka核心原理与实战避坑指南
分布式·缓存·kafka
xixixi7777710 小时前
2026 年 03 月 20 日 AI+通信+安全行业日报(来更新啦)
大数据·人工智能·安全·ai·大模型·通信
F36_9_10 小时前
大数据治理平台选型避坑:2026 年 8 大主流系统实测
大数据·数据治理
成长之路51410 小时前
【实证分析】A股上市公司企业劳动力需求数据集(2000-2023年)
大数据
奔跑的呱呱牛10 小时前
GeoJSON 在大数据场景下为什么不够用?替代方案分析
java·大数据·servlet·gis·geojson