Spark的架构
1、概述
为了更好地理解调度,先来鸟瞰一下集群模式下的Spark程序运行架构图。

2、角色
1.cluster manager
cluster manager:集群管理器,也就是master,负责集群的资源调度。
比如:为Worker Node分配CPU、内存等资源。并实时监控Worker的资源使用情况。一个Worker Node默认情况下分配一个Executor(进程)。
从图中可以看到sc和Executor之间画了一根线条,这表明:程序运行时,sc是直接与Executor进行交互的。所以,cluster manager只是负责资源的管理调度,而任务的分配和结果处理它不管。
1>Driver Program
负责程序运行的开始和结束。
用户编写的Spark程序称为Driver Program。每个Driver程序包含一个代表集群环境的SparkContext对象,程序的执行从Driver程序开始,所有操作执行结束后回到Driver程序中,在Driver程序中结束。
如果你是用spark shell,那么当你启动Spark shell的时候,系统后台自启了一个Spark驱动器程序,就是在Spark shell中预加载的一个叫作sc的SparkContext对象。如果驱动器程序终止,那么Spark应用也就结束了。
2>SparkContext对象
每个Driver Program里都有一个SparkContext对象,职责有如下两个:
SparkContext对象联系cluster manager(集群管理器),让cluster manager为Worker Node分配CPU、内存等资源。此外,cluster manager会在Worker Node上启动一个执行器(专属于本驱动程序)。
SparkContext对象和Executor进程交互,负责任务的调度分配。
2.Worker Node
Worker节点。集群上的计算节点,对应一台物理机器。
1>Worker进程
它对应Worker进程,用于和Master进程交互,向Master注册和汇报自身节点的资源使用情况,并管理和启动Executor进程。
2>Executor
负责运行Task计算任务,并将计算结果回传到Driver中。
3>Task
在执行器上执行的最小单元。比如RDD Transformation操作时对RDD内每个分区的计算都会对应一个Task。
3、Spark调度模块

如上图,之前提到Driver的sc负责和Executor交互,完成任务的分配和调度,在底层,任务调度模块主要包含两大部分:DAGScheduler、TaskScheduler。
它们负责将用户提交的计算任务按照DAG划分为不同的阶段并且将不同阶段的计算任务提交到集群进行最终的计算。整个过程可以使用下图表示:

1.RDD Objects
可以理解为用户实际代码中创建的RDD,这些代码逻辑上组成了一个DAG。
2.DAGScheduler
主要负责分析依赖关系,然后将DAG划分为不同的Stage(阶段),其中每个Stage由可以并发执行的一组Task构成,这些Task的执行逻辑完全相同,只是作用于不同的数据。
3.TaskScheduler
在DAGScheduler将这组Task划分完成后,会将这组Task提交到TaskScheduler。TaskScheduler通过Cluster Manager 申请计算资源,比如在集群中的某个Worker Node上启动专属的Executor,并分配CPU、内存等资源。接下来,就是在Executor中运行Task任务,如果缓存中没有计算结果,那么就需要开始计算,同时,计算的结果会回传到Driver或者保存在本地。
4.Scheduler的实现

任务调度模块涉及的最重要的三个类是:
1)org.apache.spark.scheduler.DAGScheduler前面提到的DAGScheduler的实现。
2)org.apache.spark.scheduler.TaskScheduler
它的作用是为创建它的SparkContext调度任务,即从DAGScheduler接收不同Stage的任务,并且向集群提交这些任务,并为执行特别慢的任务启动备份任务。
3)org.apache.spark.scheduler.SchedulerBackend
是一个trait,作用是分配当前可用的资源,具体就是向当前等待分配计算资源的Task分配计算资源(即Executor),并且在分配的Executor上启动Task,完成计算的调度过程。
任务调度流程图

根据对以上信息的理解,我自己画了一个任务执行流程-关系图,如下:

上一篇:Spark框架核心概念
下一篇:Spark Shuffle