Spark核心:深入理解RDD pipeline

Spark核心:深入理解RDD pipeline

1. 引言:为什么要理解RDD Pipeline?

在Spark中,RDD的转换操作通常不会立即执行,而是构建出一个计算链路。这种“惰性求值”的特性是Spark性能优化的基石。理解RDD Pipeline,也就是RDD的依赖关系和Stage划分机制,能帮助我们编写更高效的Spark程序,有效避免数据倾斜和重复计算。

2. RDD的依赖关系:血缘的两种形态

RDD的每个分区都由其父RDD通过特定的操作转换而来,这种父子关系称为“依赖”。Spark中定义了两种核心依赖:

2.1 窄依赖

父RDD的每个分区至多被子RDD的一个分区使用。例如mapfilterunion等操作产生窄依赖。在窄依赖中,数据不需要跨节点移动,可以流水线化执行。

2.2 宽依赖

父RDD的每个分区会被子RDD的多个分区使用。典型的如groupByKeyreduceByKeyjoin等操作。宽依赖会导致Shuffle,即将数据按照Key的哈希值重新分发到不同节点,这个过程涉及大量的网络和磁盘IO。

3. Stage划分:Pipeline的物理边界

当遇到一个Action操作时,Spark DAGScheduler会根据RDD的依赖关系将作业划分成不同的Stage。划分的核心原则是:遇到宽依赖就进行Stage切分。在一个Stage内部,所有的窄依赖可以合并为一条流水线,数据在内存中依次通过多个算子,无需落地磁盘,这极大地提高了效率。

4. 窄依赖与宽依赖对比

下表系统对比了窄依赖和宽依赖的关键区别,有助于在实际编码中做出判断:

对比维度窄依赖宽依赖
计算特征流水线计算,无需Shuffle