Spark基础学习笔记19:RDD的依赖与Stage划分

零、本讲学习目标

  1. 理解RDD的宽依赖与窄依赖
  2. 理解Spark根据DAG将计算划分多个阶段

一、RDD的依赖

  • 在Spark中,对RDD的每一次转化操作都会生成一个新的RDD,由于RDD的懒加载特性,新的RDD会依赖原有RDD,因此RDD之间存在类似流水线的前后依赖关系。这种依赖关系分为两种:窄依赖和宽依赖。

(一)窄依赖

  • 窄依赖是指父RDD的一个分区最多被子RDD的一个分区所用。也就是说,父RDD的分区与子RDD的分区的对应关系为一对一或多对一。例如,map()、filter()、union()、join()等操作都会产生窄依赖。

1、map()与filter()算子

  • 一对一的依赖
    在这里插入图片描述

2、union()算子

  • 多对一的依赖
    在这里插入图片描述

3、join()算子

  • 多对一的依赖
    在这里插入图片描述
  • 对于窄依赖的RDD,根据父RDD的分区进行流水线操作,即可计算出子RDD的分区数据,整个操作可以在集群的一个节点上执行。

(二)宽依赖

  • 宽依赖是指父RDD的一个分区被子RDD的多个分区所用。也就是说,父RDD的分区与子RDD的分区的对应关系为多对多。例如,groupByKey()、reduceByKey()、sortByKey()等操作都会产生宽依赖。

1、groupBy()算子

在这里插入图片描述

2、join()算子

在这里插入图片描述

  • join()操作的依赖关系分两种情况:RDD的一个分区仅和另一个RDD中已知个数的分区进行组合,这种类型的join()操作是窄依赖,其他情况则是宽依赖。
  • 在宽依赖关系中,RDD会根据每条记录的key进行不同分区的数据聚集,数据聚集的过程称作Shuffle,类似MapReduce中的Shuffle过程。举个生活中的例子,4个人一起打牌,打完牌后需要进行洗牌,这4个人相当于4个分区,每个人手里的牌则相当于分区里的数据,洗牌的过程可以理解为Shuffle。因此,Shuffle其实就是不同分区之间的数据聚集或者说数据混洗。Shuffle是一项耗费资源的操作,因为它涉及磁盘I/O、数据序列化和网络I/O。

3、reduceByKey()算子

  • 对一个RDD进行reduceByKey()操作,RDD中相同key的所有记录将进行聚合,而key相同的所有记录可能不在同一个分区中,甚至不在同一个节点上,但是该操作必须将这些记录聚集到一起进行计算才能保证结果准确,因此reduceByKey()操作会产生Shuffle,也会产生宽依赖。

(三)两种依赖的比较

  • 在数据容错方面,窄依赖要优于宽依赖。当子RDD的某一个分区的数据丢失时,若是窄依赖,则只需重算和该分区对应的父RDD分区即可,而宽依赖需要重算父RDD的所有分区。在groupByKey()操作中,若RDD2的分区1丢失,则需要重新计算RDD1的所有分区(分区1、分区2、分区3)才能对其进行恢复。此外,宽依赖在进行Shuffle之前,需要计算好所有父分区的数据,若某个父分区的数据未计算完毕,则需要等待。

二、Stage划分

(一)有向无环图

  • 在Spark中,对每一个RDD的操作都会生成一个新的RDD,将这些RDD用带方向的直线连接起来(从父RDD连接到子RDD)会形成一个关于计算路径的有向无环图,称为DAG(Directed Acyclic Graph)。
    在这里插入图片描述

(二)Stage划分依据

  • Spark会根据DAG将整个计算划分为多个阶段,每个阶段称为一个Stage。每个Stage由多个Task任务并行进行计算,每个Task任务作用在一个分区上,一个Stage的总Task任务数量是由Stage中最后一个RDD的分区个数决定的
  • Stage的划分依据为是否有宽依赖,即是否有Shuffle。Spark调度器会从DAG图的末端向前进行递归划分,遇到Shuffle则进行划分,Shuffle之前的所有RDD组成一个Stage,整个DAG图为一个Stage。

1、两阶段案例

  • 经典的单词计数执行流程的Stage划分如下图所示。
    在这里插入图片描述
  • 上图中的依赖关系一共可以划分为两个Stage:从后向前进行递归划分,RDD3到RDD4的转换是Shuffle操作,因此在RDD3与RDD4之间划开,继续向前查找,RDD1、RDD2、RDD3之间的关系为窄依赖,因此为一个Stage;整个转换过程为一个Stage。

3、三阶段案例

  • 下图中的依赖关系一共可以划分为3个Stage:从后向前进行递归划分,由于RDD6到RDD7的转换是Shuffle操作,因此在RDD6与RDD7之间划开,然后继续向前查找,RDD3、RDD4、RDD5、RDD6为一个Stage;由于RDD1到RDD2的转换是Shuffle操作,因此在RDD1与RDD2之间划开,然后继续向前查找,RDD1为一个Stage;整个转换过程为一个Stage。
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/howard2005/article/details/123926097