区分:union(),coalesce () 和 repartition ()

一、合并的对象:数据 vs 分区

Spark 中需要区分两个概念:

  • 数据(Data):RDD 中的元素(如 [1, 2, 3])。
  • 分区(Partitions):数据的物理存储单位,分布在集群的不同节点上。

这三个算子的 "合并" 对象不同:

  • union():合并数据(将多个 RDD 的元素叠加)。
  • coalesce () 和 repartition ():合并分区(调整数据的物理分布)。

二、union ():合并数据(不改变分区)

核心逻辑
  • 将多个 RDD 的元素合并成一个新的 RDD。
  • 分区数 = 原 RDD 分区数之和,每个 RDD 的分区保持独立。
示例

假设有两个 RDD:

scala

复制代码
// RDD 1:2个分区
val rdd1 = sc.parallelize(Seq(1, 2, 3), 2)  // 分区0: [1, 2], 分区1: [3]

// RDD 2:3个分区
val rdd2 = sc.parallelize(Seq(4, 5, 6), 3)  // 分区0: [4], 分区1: [5], 分区2: [6]

执行 union ():

scala

复制代码
val unionRdd = rdd1.union(rdd2)  // 共5个分区(2+3)
unionRdd.glom().collect()        // 查看分区内容
结果可视化

plaintext

复制代码
rdd1:
  分区0 -> [1, 2]
  分区1 -> [3]

rdd2:
  分区0 -> [4]
  分区1 -> [5]
  分区2 -> [6]

union_rdd:
  分区0 -> [1, 2]    # rdd1的分区0
  分区1 -> [3]       # rdd1的分区1
  分区2 -> [4]       # rdd2的分区0
  分区3 -> [5]       # rdd2的分区1
  分区4 -> [6]       # rdd2的分区2
关键点
  • 数据合并:rdd1 和 rdd2 的元素被放到一起。
  • 分区独立:每个 RDD 的分区保持原样,只是简单叠加。

三、coalesce () 和 repartition ():合并分区(调整数据分布)

核心逻辑
  • 合并分区:将同一个 RDD 的多个分区物理合并为更少的分区(或通过 shuffle 重新分布)。
  • 数据可能重新分布:通过移动数据实现分区合并。
示例:coalesce (2)

假设初始 RDD 有 4 个分区:

scala

执行 coalesce (2)(合并为 2 个分区):

scala

复制代码
val coalescedRdd = rdd.coalesce(2)  // 合并为2个分区
coalescedRdd.glom().collect()
结果可视化
复制代码
原 rdd:
  分区0 -> [1, 2]
  分区1 -> [3, 4]
  分区2 -> [5, 6]
  分区3 -> [7, 8]

coalesced_rdd(合并相邻分区):
  分区0 -> [1, 2, 3, 4]    # 合并原分区0和1
  分区1 -> [5, 6, 7, 8]    # 合并原分区2和3
repartition () 的区别

如果用 repartition (2):

scala

复制代码
val repartitionedRdd = rdd.repartition(2)  // 重新分区为2个
repartitionedRdd.glom().collect()
结果可视化
复制代码
repartitioned_rdd(通过shuffle均匀分布):
  分区0 -> [1, 3, 5, 7]    # 数据被打散到新分区
  分区1 -> [2, 4, 6, 8]
关键点
  • 分区合并:将原本分散的分区物理合并为更少的分区。
  • 数据移动:coalesce () 尽量不 shuffle(合并相邻分区),而 repartition () 强制 shuffle 以保证数据均匀。

四、对比总结

算子 合并对象 是否改变分区数 数据是否 shuffle 核心场景
union() 多个 RDD 的数据 是(叠加原分区数) 快速合并多个数据集
coalesce() 同一个 RDD 的分区 是(通常减少) 否(默认) 减少分区数,避免 shuffle
repartition() 同一个 RDD 的分区 是(任意调整) 彻底重分区,解决数据倾斜

五、常见误区解答

1. union () 会合并分区吗?

不会!union () 只是将多个 RDD 的分区简单叠加,分区数等于原 RDD 分区数之和。例如:

scala

复制代码
val rdd1 = sc.parallelize(Seq(1, 2), 1)  // 1个分区
val rdd2 = sc.parallelize(Seq(3, 4), 1)  // 1个分区
val unionRdd = rdd1.union(rdd2)           // 2个分区(1+1)
2. coalesce () 和 repartition () 的合并有什么不同?
  • coalesce() :通过合并相邻分区实现,不 shuffle(默认),可能导致数据倾斜。

    scala

    复制代码
    rdd.coalesce(1)  // 合并为1个分区,数据可能集中在一个节点
  • repartition() :通过 shuffle 重新分布数据,分区更均匀,但开销大。

    scala

    复制代码
    rdd.repartition(10)  // 增加到10个分区,数据被打散

六、一句话总结

  • union():多个 RDD 的数据合并(分区数叠加)。
  • coalesce()/repartition():同一个 RDD 的分区合并(调整数据分布)。
相关推荐
小王毕业啦15 小时前
2005-2024年 省级-总抚养比、儿童抚养比、老年人抚养比数据(xlsx)
大数据·人工智能·数据挖掘·数据分析·社科数据·实证分析·经管数据
2501_9272835816 小时前
荣联汇智助力天津艺虹打造“软硬一体”智慧工厂,全流程自动化引领印刷包装行业数智变革
大数据·运维·数据仓库·人工智能·低代码·自动化
还是奇怪17 小时前
AI 提示词工程入门:用好的语言与模型高效对话
大数据·人工智能·语言模型·自然语言处理·transformer
Data_Journal19 小时前
如何使用cURL更改User Agent
大数据·服务器·前端·javascript·数据库
weixin_4462608519 小时前
城市智能化的底层基石:基于腾讯地图服务生态的移动定位与导航架构指引
大数据·人工智能·架构
qq_2837200519 小时前
Vibe Coding 氛围编程入门教程:AI 时代的全新开发范式(零基础到实战)
大数据·人工智能
Volunteer Technology20 小时前
ES并发控制
大数据·elasticsearch·搜索引擎
小飞象—木兮21 小时前
《销售数据分析标准实践手册》:核心内涵与关键指标、落地销售数据分析的全流程···(附相关材料下载)
大数据·人工智能·数据挖掘·数据分析
howard200521 小时前
2.4.3 集群模式运行Spark项目
spark·项目打包·提交运行
KmSH8umpK21 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第三篇
redis·分布式·wpf