Spark概述
Spark-RDD概述
Spark-RDD-依赖关系
-
在Apache Spark中,RDD(Resilient Distributed Dataset)是一种基本的抽象数据结构,代表了分布式的、不可变的数据集。
-
RDD之间的依赖关系在Spark中非常重要,因为它们决定了Spark作业的执行流程和优化方式。
- 依赖关系描述了RDD之间的转换关系以及它们之间的依赖关系。简单来说,它指的是RDD之间如何相互关联的。
-
RDD只支持粗粒度转换,即在大量记录上执行的单个操作。
-
将创建RDD的一系列Lineage(血统)记录下来,以便恢复丢失的分区。
-
RDD的Lineage会记录RDD的元数据信息和转换行为,当该RDD的部分分区数据丢失时,它可以根据这些信息来重新运算和恢复丢失的数据分区。
在Spark中,RDD的依赖关系分为两种类型:窄依赖(Narrow Dependency)和宽依赖(Wide Dependency)。
1.窄依赖
-
窄依赖发生在父RDD的每个分区最多只被子RDD的一个分区所使用的情况下。
-
这意味着每个父RDD的分区只需要传输给子RDD的对应分区,而不需要进行数据的混洗(shuffle)操作。
-
窄依赖通常发生在一对一的转换操作,比如map、filter等。
-
因为每个父RDD分区的数据只会被用于生成一个子RDD分区,所以数据的分区关系可以被简单地维护。
2.宽依赖
-
宽依赖发生在父RDD的每个分区可以被子RDD的多个分区所使用的情况下。
-
这意味着在子RDD的计算过程中,需要将父RDD的数据进行混洗操作,以确保正确的数据分区被传输给子RDD的各个分区。
-
宽依赖通常发生在需要进行数据混洗的操作,比如groupByKey、reduceByKey等。
-
因为这些操作需要将具有相同键的数据重新分组到同一个分区中,所以需要进行数据的混洗。
具有宽依赖的transformations包括:sort、reduceByKey、groupByKey、join和调用rePartition函数的任何操作。
宽依赖对Spark去评估一个transformations有更加重要的影响,比如对性能的影响。
在不影响业务要求的情况下,要尽量避免使用有宽依赖的转换算子,因为有宽依赖,就一定会走shuffle,影响性能。
3.作业、阶段和任务的关系
当执行一个Spark作业时,Spark会将作业划分为多个阶段(Stage)。这个划分过程基于RDD的依赖关系以及数据的分区情况。
3.1作业(Job):
-
作业是由一系列RDD的转换操作组成的有向无环图(DAG)。
-
DAG中的每个节点代表一个RDD的转换操作,每个边表示一个RDD之间的依赖关系。
-
作业的执行是惰性的,只有当遇到一个动作操作(Action)时,Spark才会开始执行作业。
3.2阶段(Stage):
- 一个阶段包含了一组可以并行计算的任务,这些任务可以在相同的数据上独立地运行。
- 阶段的划分基于RDD之间的依赖关系。每当遇到一个宽依赖(Wide Dependency),即需要进行数据混洗(shuffle)的操作,就会划分出一个新的阶段。
- 每个阶段中的任务都会处理上一个阶段输出的数据,这些数据被分区为任务数量相等的数据块。
3.3任务(Task):
-
任务是作业执行的最小单位,它们由Executor上的线程执行。
-
每个任务都会处理一个RDD分区的数据,这些数据来自上一个阶段的相应分区。
-
任务的数量通常等于上一个阶段输出的RDD分区的数量。
-
任务之间可以在不同节点上并行执行,但是同一个任务内部是串行执行的。