Spark内核架构
为了更加清晰的知道Spark作业是怎么运行的,有必要知道Spark的内核运行机制,我们以Standalone模式为例,剖析Spark的内核运行架构,内核架构图如下所示:
我们首先在一台机器上提交Spark Application,通过Spark-submit脚本进行提交,提交Spark Application的这台机器会启动一个Driver进程,Driver进程启动之后,会执行我们的Spark作业,每个Spark作业首先都会创建并初始化SparkContext(我们这里只研究SparkContext,至于SQLContext和HiveContext,原理应该差不多,没有具体研究)。
SparkContext会创建两个重要的组件:TaskScheduler和DAGScheduler。
其中创建完TaskScheduler会通过AppClient(ClientEndPoint)向Spark集群中的Master注册Application的信息(也即ApplicationDescription里面封装了AppName,executorMemory,coresPerExecutor等),Master接收到TaskScheduler发送过来的Application信息之后,会使用自己的资源调度算法,去Worker节点上启动executor来运行我们的Application,Worker节点启动成功Executor后,会通过CoarseGrainedExecutorBackend向Driver反向注册自己的信息,当所有的Executor都向TaskScheduler注册了自己的信息之后,SparkContext就初始化完成。
SparkContext初始化完成之后,接着执行我们Spark Application,当执行到一个action操作时,就会触发程序的运行,首先会创建一个Job,接着Job被提交到DAGScheduler上,Job被Stage划分算法,划分为多个stage,并为每个stage创建一个TaskSet,接着被提交到TaskScheduler上,TaskScheduler会把TaskSet里的每个task分配到对应的(Task分配算法)Executor上执行。Executor接收到Task之后,首先会将task进行拷贝,反序列化等操作,使用TaskRunner来封装这个task,接着从线程池中取出一个线程来执行这个task。
以此类推,Spark分批次提交task,直到所有的task运行结束,整个Spark Application就运行结束。
我看的版本是1.6,具体源码在core文件下的:SparkContext.scala(520行左右)、TaskShcedulerImple.scala的initialize()方法、SparkDepolySchedulerBackend.scala等。