RDD的依赖关系,以及造成的stage的划分

本文解析了Spark中RDD的依赖关系,包括窄依赖和宽依赖的区别,以及这些依赖如何影响Stage的划分。深入探讨了RDD的生命线和依赖机制,以及在不同依赖下数据的分布情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:RDD的依赖关系

1.在代码中观察

    val data = Array(1, 2, 3, 4, 5)
  val distData = sc.parallelize(data)
  val resultRDD = distData.flatMap(v => (1 to v)).map(v => (v%2,1)).reduceByKey(_+_)
  resultRDD.toDebugString ## 查看RDD的依赖情况

在这里插入图片描述

2.解释

  + —处表示,这是两个不同的stage

  同时可以知道shuffledRDD依赖于MapPartitionRDD,MapPartitionRDD依赖于MapPartitionRDD,MapPartitionRDD依赖于ParalleCollectionRDD

 [2]表示有两个分区
在这里插入图片描述

3.RDD依赖

  lineage: 生命线
  依赖于RDD之间的依赖,后续的RDD数据是从之前的RDD中获取
  由于存在RDD的依赖,当一个后续的RDD执行失败的情况下(某个Task执行失败,eg:数据丢失),可以从父RDD中重新执行
  RDD依赖父RDD,依赖的父RDD可以有多个;

    特例:第一个RDD是没有父RDD的
  RDD的内部是由多个Partiiton构成的,所以RDD的依赖实质上就是RDD中Partition的依赖关系

4.依赖的情况

  当前RDD中的每个分区的数据到下一个RDD都对应一个分区
   即:一个分区的数据输出到下一个RDD的时候还是在同一个分区,也就是一对一
  当前RDD中的多个分区的数据到下一个RDD的时候输出到同一个分区,当前RDD的中一个分区的数据到下一个RDD的时候输出到多个分区,也就是多对多

5.依赖分类

窄依赖:
  子RDD中的每个分区的数据都来自于常数个父RDD的分区,而且父RDD每个分区的数据到子RDD的时候一定在一个分区中
  不存在shuffle过程,所有操作在一起进行
宽依赖:
  子RDD中的每个分区的数据都依赖所有父RDD的所有的分区数据,而且父RDD的每个分区的数据到子RDD的时候不一定在一个分区中
  存在shuffle过程,需要等待上一个RDD的所有Task执行完成
在这里插入图片描述
在这里插入图片描述
注意点:
  join有时候是宽依赖,有时候是窄依赖,这个要看分区数量会不会改变。

6.算子与依赖之间的关系

  原本以为Transformation的算子是窄依赖,Action算子是宽依赖。
  现在理解更深了一下,发现他们是两个概念,不要混淆。

二:stage的划分

1.Spark Application Job的Stage划分规则

  RDD在调用transformation类型的函数时候形成DAG执行图(RDD的依赖)
  RDD在调用action类型函数的时候会触发job的执行
  在Driver中使用DAGScheduler对DAG图进行Stage的划分
    从DAG图的最后一步(结果输出的那一步)往前推,如果发现API是宽依赖(ShuffledRDD), 就结束推断,将此时构成的DAG图称为一个Stage,然后继续往前推断,直到第一个RDD
    ====> Stage与Stage之间的分割是宽依赖

三:两种RDD依赖的复习

1.说明

  主要是添加一个知识点。

  什么情况下父RDD需要执行。

2.不是不执行

在这里插入图片描述

RDD依赖关系对应的执行流程可以分为两种情况:窄依赖和宽依赖。 1. 窄依赖(Narrow Dependency): - 输入RDD的每个分区只依赖于一个父RDD的分区或者少数几个父RDD的分区。 - 在执行过程中,每个父RDD的分区会被直接传递给子RDD的对应分区进行处理,无需进行数据重组和Shuffle操作。 - 窄依赖的执行流程比较简单,数据可以高效地在各个阶段传递和处理。 2. 宽依赖(Wide Dependency): - 输入RDD的每个分区依赖于多个父RDD的分区,需要进行数据重组和Shuffle操作。 - 在执行过程中,数据需要经过Shuffle操作重新分区并按照键(Key)进行排序和合并。 - 宽依赖的执行流程相对较复杂,会引入磁盘IO和网络传输,性能开销较大。 整个RDD的执行流程可以概括如下: 1. 根据RDD依赖关系构建有向无环图(DAG)。 2. 根据DAG图划分为多个Stage,每个Stage包含一组具有相同转换操作的任务。 3. 从第一个Stage开始,按照依赖关系逐个执行Stage根据依赖关系和分区的划分将数据传递给子RDD的对应分区。 4. 对于窄依赖,数据直接传递给子RDD进行处理;对于宽依赖,需要进行Shuffle操作,将数据进行重新分区和排序合并。 5. 每个Stage的任务可以在不同的Executor上并行执行,提高计算效率。 6. 最后一个Stage的输出结果可以写入到输出数据源(如HDFS、数据库等)。 需要注意的是,RDD依赖关系和执行流程是根据DAG图来确定的,Spark会根据DAG图的结构和依赖关系划分任务和执行计划,以实现高效的数据处理和计算。 希望以上信息对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值