Spark源码剖析(二):Spark内核架构深度剖析
千言万语不如一张图!
Spark应用运行原理图
流程梳理
- 使用standalone提交模式,将我们编写好的Application打成jar包上传到某Spark节点上,通过spark-submit提交Application,该命令运行后在该节点会通过
反射
的方式,创建和构造一个DriverActor进程,就是我们经常说的Driver,该进程负责执行我们的Application
,也就是我们编写的代码。
- 就像我们编写代码一样,Driver进程首先构造
SparkConf
,接着创建SparkContext对象
,SparkContext在初始化的时候,会构造DAGSchedule和TaskScheduler
。
TaskSchedule
接着通过启动自己的后台进程,去连接Master,向Master注册Application。
- Master收到Application注册的请求后,会使用自己的
资源调度算法
,为该Application分配运行资源,分配完成后就通知Spark集群上相应的Worker节点,为这个Application启动分配数量的Executor。
Executor启动之后会自己反向注册到TaskScheduler上去
。
- 当所有Executor完成反向注册后,DriverActor继续执行应用程序中的代码,
每执行到一个action操作,就会创建一个Job
,Driver会将Job提交给DAGSchedule,DAGSchedule会将job基于Stage划分算法划分为多个stage
,然后每个stage作为TaskSets
提交到TaskSchedule,随后TaskSchedule会将TaskSet里每一个Task(task分配算法
)提交到Executor上执行。(task分配算法)
- Executor每接收到一个task,都会用
TaskRunner
(将我们编写的代码,也就是要执行的算子以及函数,拷贝,反序列化,然后执行task)来封装task,然后从线程池
(每一个Executor都有一个线程池)里取出一个线程,执行这个task。
- Task有两种,
shuffleMapTask和ResultTask
,每个Job中只有最后一个stage是ResultTask。
- 所以最后整个spark应用程序的执行,
就是stage分批次作为taskset提交到Executor执行,每个task针对RDD的一个partition,执行我们定义的算子和函数
,以此类推,直到所有操作执行结束为止。
注意:这是总体架构概括,后面的博文将对其中的各个组件和功能进行深度剖析!