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(即输出一个值或结果)

Spark教程(二)—— 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 中跨节点重新分配数据的过程,是宽依赖操作的实现机制。

关键特性

  1. 触发条件:当操作需要按 key 重新分组或聚合数据时(如 reduceByKey、join 等)
  2. 执行过程
    • Map 阶段:每个节点处理本地数据并生成中间结果
    • Shuffle 阶段:按 key 将数据重新分区并跨节点传输
    • Reduce 阶段:接收数据并执行最终计算
  3. 性能影响
    • 涉及磁盘 I/O、网络传输和数据序列化
    • 是 Spark 中最昂贵的操作之一
  4. 优化方法
    • 尽量减少 shuffle 操作
    • 使用 reduceByKey 替代 groupByKey
    • 合理设置分区数

二、血缘关系(Lineage)

定义:RDD 通过记录其从其他 RDD 派生的历史(即如何从父 RDD 计算得到)来实现容错。

关键特性

  1. 组成要素

    • 父 RDD 的引用
    • 转换函数(如 map、filter 等)
  2. 容错机制

    • 当某个分区丢失时,可根据血缘关系重新计算
    • 不需要数据复制即可实现容错
  3. 可视化表示

    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)

  1. 定义:对数据的最小单元(如单个记录)进行操作
  2. Spark 实现
    • RDD 的转换操作(map、filter 等)是细粒度的
    • 每个记录独立处理
  3. 优点
    • 灵活性高
    • 可以精确控制数据处理逻辑

粗粒度(Coarse-grained)

  1. 定义:对数据块或分区进行批量操作
  2. Spark 实现
    • 整个分区的计算作为一个任务执行
    • 调度以分区为单位
  3. 优点
    • 减少调度开销
    • 提高批量处理效率

四、流水线(Pipelining)

定义:Spark 将多个窄依赖操作合并为一个阶段(stage)连续执行的优化技术。

关键特性

  1. 执行条件

    • 仅适用于窄依赖操作序列
    • 不需要 shuffle 的操作
  2. 工作原理

    • 多个转换操作合并为一个任务
    • 数据在内存中连续传递,不写磁盘
  3. 示例

    rdd.map(f1).filter(f2).map(f3)  # 这三个操作会被流水线化执行
    
  4. 性能优势

    • 减少中间结果的存储开销
    • 提高 CPU 缓存利用率
    • 降低任务启动开销

五、核心概念关系图

血缘关系(Lineage)
  │
  ├─ 构建DAG → 划分Stage → 任务调度
  │     │
  │     ├─ 窄依赖 → 流水线执行
  │     │
  │     └─ 宽依赖 → Shuffle
  │
  └─ 容错恢复机制

理解这些核心概念对于优化 Spark 作业至关重要,特别是在处理大规模数据集时,合理利用这些特性可以显著提高性能。

posted @ 2025-04-28 06:52  快乐星猫i  阅读(43)  评论(0)    收藏  举报