1.RDD的依赖关系

1.1  WordCount中的RDD

宽依赖窄依赖+stage划分

RDD和它依赖的父RDD(s)的关系有两种不同的类型,即窄依赖(narrow dependency)和宽依赖(wide dependency)。

1.2  窄依赖

窄依赖指的是每一个父RDD的Partition最多被子RDD的一个Partition使用

总结:窄依赖我们形象的比喻为独生子女

1.3  宽依赖

宽依赖指的是多个子RDD的Partition会依赖同一个父RDD的Partition

总结:窄依赖我们形象的比喻为超生


窄依赖:可以理解为独生子女

宽依赖:可以理解为超生

如上图所示,一个文件被textFile后经过两次转换,每次转换后生成的新的RDD都和原分区一一对应,为窄依赖关系。

当map算子计算失败时,可以直接去上一步的RDD中重新计算,而不需要其他的分区参与。但是如果最后的action算子在计算某个RDD时,计算失败,将会到上一层的多个分区中寻找依赖关系,比较麻烦。

stage解决了这个问题,它根据宽依赖和窄依赖的关系进行换分,如上图将存在窄依赖关系的RDD换分成为一个stage。

宽依赖窄依赖+stage划分

2.  DAG的生成

2.1  什么是DAG

DAG(Directed Acyclic Graph)叫做有向无环图,原始的RDD通过一系列的转换就就形成了DAG,根据RDD之间的依赖关系的不同将DAG划分成不同的Stage,对于窄依赖,partition的转换处理在Stage中完成计算。对于宽依赖,由于有Shuffle的存在,只能在parent RDD处理完成后,才能开始接下来的计算,因此宽依赖是划分Stage的依据

宽依赖窄依赖+stage划分

2.2  DAG在spark中的应用

宽依赖窄依赖+stage划分

  • 在Spark应用中,整个执行流程在逻辑上会形成有向无环图(DAG)。
  • Action算子触发之后,将所有累积的算子形成一个有向无环图,然后由调度器调度该图上的任务进行运算。
  • Spark的调度方式与MapReduce有所不同。Spark根据RDD之间不同的依赖关系切分形成不同的阶段(Stage),一个阶段包含一系列函数执行流水线。
  • 图中的A、B、C、D、E、F分别代表不同的RDD,RDD内的方框代表分区。
  • 数据从HDFS输入Spark,形成RDD A和RDD C,RDD C上执行map操作,转换为RDD D,RDD B和RDD E执行join操作,转换为F,而在B和E连接转化为F的过程中又会执行Shuffle,最后RDD F通过函数saveAsSequenceFile输出并保存到HDFS中。

2.3.  Spark的任务提交机制

 宽依赖窄依赖+stage划分

作业执行流程描述:

1、客户端启动后直接运行用户程序,启动Driver相关的工作:DAGSchedulerBlockManagerMaster等。

2、客户端的DriverMaster注册。

3Master还会让Worker启动ExeuctorWorker创建一个ExecutorRunner线程,ExecutorRunner会启动ExecutorBackend进程。

4ExecutorBackend启动后会向DriverSchedulerBackend注册。DriverDAGScheduler解析作业并生成相应的Stage,每个Stage包含的Task通过TaskScheduler分配给Executor执行。

5、所有stage都完成后作业结束。


简单理解:

首先Driver和master通信(提交任务,申请资源,传送driverUrl地址)如 spark-submit xxx.jar --total-executor-cores 2 --executor-memory 512,该命令执行后master会根据提交的信息申请资源;

master主要做几件事情:1拿出所有workers上的资源;2按照资源的大小进行排序;3按照排序顺序取资源;4让worker启动executor。

最后把任务换分为stage,将stage添加到taskSet中。循环taskset,将task下发。


相关文章: