Spark
2025/4/24
Spark基础
原来的MapReduce是基于硬盘计算的。
现在的Spark是基于内存计算的。
Spark特点:简单、快速(内存计算、DAG执行引擎:有向无环图)、规模化、统一性
RDD运行原理
RDD弹性分布式数据集,它是Spark计算的核心。
弹性:在计算上具有容错性,spark是一个计算框架,如果某一个节点挂了,可以自动进行计算之间血缘关系的追踪。
分布式:hdfs上数据是跨节点的,那么Spark的计算也是要跨界点的。
数据集:可以将数组、文件等一系列数据的集合转换为RDD。
RDD只读,不能修改,如果要改,就要转化生成一个新的RDD。
RDD提供了一系列的操作,“转化”(每一次产生不同的RDD)和“动作”(最后一个RDD经过“动作”操作进行转换并输出)。这一系列处理称为一个血缘关系,即DAG拓扑排序的结果。
RDD之间的依赖关系👇
RDD的数据运算有两种类型, 分别是 "行动" 和 "转换". 前者用于执行计算并指定输出形式, 后者指定RDD之间的相互依赖关系. "行动" 和 "转换" 类型的区别是转换操作(比如map、filter、groupBy、join等)接受RDD并返回RDD, 而行动操作(比如count、collect等)接受RDD但是返回非RDD(即输出一个值或结果)
2.RDD 血缘关系 (Lineage)
- RDD 通过血缘关系记录其衍生过程
- 本质是一个有向无环图(DAG)
- 用于容错恢复,当某个分区丢失时可以根据血缘重新计算
python
# 示例血缘关系
rdd1 = sc.textFile("data.txt") # 第一个RDD
rdd2 = rdd1.map(lambda x: x.split()) # 窄依赖
rdd3 = rdd2.filter(lambda x: len(x)>0) # 窄依赖
rdd4 = rdd3.map(lambda x: (x[0],1)) # 窄依赖
rdd5 = rdd4.reduceByKey(lambda a,b: a+b) # 宽依赖
3.shuffle
4.窄依赖和宽依赖
RDD 之间的依赖关系分为两种主要类型:
1. 窄依赖 (Narrow Dependency)
-
每个父 RDD 的分区最多被子 RDD 的一个分区所依赖
-
特点:
- 可以在单个节点上完成计算
- 不需要跨节点数据传输(无 shuffle)
- 高效,失败恢复成本低
-
常见操作:
python
map(), filter(), union(), join()(当使用相同的分区器时)
2. 宽依赖 (Wide Dependency/Shuffle Dependency)
-
父 RDD 的一个分区可能被子 RDD 的多个分区依赖
-
特点:
- 需要跨节点数据传输(shuffle)
- 计算成本高,失败恢复成本高
- 是划分 stage 的边界
-
常见操作:
python
groupByKey(), reduceByKey(), join()(不同分区器时), distinct(), repartition()
5.阶段的划分
- 窄依赖可以实现流水线优化
- 宽依赖无法实现流水线优化
Spark RDD 核心概念详解
一、Shuffle(洗牌/混洗)
定义:Shuffle 是 Spark 中跨节点重新分配数据的过程,是宽依赖操作的实现机制。
关键特性:
- 触发条件:当操作需要按 key 重新分组或聚合数据时(如 reduceByKey、join 等)
- 执行过程:
- Map 阶段:每个节点处理本地数据并生成中间结果
- Shuffle 阶段:按 key 将数据重新分区并跨节点传输
- Reduce 阶段:接收数据并执行最终计算
- 性能影响:
- 涉及磁盘 I/O、网络传输和数据序列化
- 是 Spark 中最昂贵的操作之一
- 优化方法:
- 尽量减少 shuffle 操作
- 使用
reduceByKey替代groupByKey- 合理设置分区数
二、血缘关系(Lineage)
定义:RDD 通过记录其从其他 RDD 派生的历史(即如何从父 RDD 计算得到)来实现容错。
关键特性:
组成要素:
- 父 RDD 的引用
- 转换函数(如 map、filter 等)
容错机制:
- 当某个分区丢失时,可根据血缘关系重新计算
- 不需要数据复制即可实现容错
可视化表示:
rdd1 = sc.textFile("data.txt") # 血缘起点 rdd2 = rdd1.map(lambda x: x.split()) # 转换1 rdd3 = rdd2.filter(lambda x: len(x)>0) # 转换2血缘关系:textFile → map → filter
三、细粒度与粗粒度
细粒度(Fine-grained)
- 定义:对数据的最小单元(如单个记录)进行操作
- Spark 实现:
- RDD 的转换操作(map、filter 等)是细粒度的
- 每个记录独立处理
- 优点:
- 灵活性高
- 可以精确控制数据处理逻辑
粗粒度(Coarse-grained)
- 定义:对数据块或分区进行批量操作
- Spark 实现:
- 整个分区的计算作为一个任务执行
- 调度以分区为单位
- 优点:
- 减少调度开销
- 提高批量处理效率
四、流水线(Pipelining)
定义:Spark 将多个窄依赖操作合并为一个阶段(stage)连续执行的优化技术。
关键特性:
执行条件:
- 仅适用于窄依赖操作序列
- 不需要 shuffle 的操作
工作原理:
- 多个转换操作合并为一个任务
- 数据在内存中连续传递,不写磁盘
示例:
rdd.map(f1).filter(f2).map(f3) # 这三个操作会被流水线化执行性能优势:
- 减少中间结果的存储开销
- 提高 CPU 缓存利用率
- 降低任务启动开销
五、核心概念关系图
血缘关系(Lineage) │ ├─ 构建DAG → 划分Stage → 任务调度 │ │ │ ├─ 窄依赖 → 流水线执行 │ │ │ └─ 宽依赖 → Shuffle │ └─ 容错恢复机制理解这些核心概念对于优化 Spark 作业至关重要,特别是在处理大规模数据集时,合理利用这些特性可以显著提高性能。

浙公网安备 33010602011771号