赘述
本系列的文章将会从spark源码的角度来分析spark任务提交集群到运行结束这个过程的处理逻辑,所以对Spark编程的熟练度要求比较高。
Spark是基于内存的大数据处理计算引擎。 使用 Scala语言实现,可以像操作本地集合对象一样轻松地操作分布式数据集,其将 Scala 用作其应用程序框架,同时支持java,python开发。这篇文章主要对spark的任务流程做一个简单的深度解析。
正解
下面将从某一台提交spark应用的机器讲解整个任务流程,
1、spark任务提交
首先通过azkaban等任务调度平台(spark-submit)将spark的jar包(application)提交到集群运行后,这时会启动一个Driver进程(client和cluster的Driver位置是不同的),Driver进程会执行application应用程序。
2、SparkContext初始化
spark主类的代码首先是构造SparkConf,再构造SparkContext,如图:
sparkContext初始化,最重要的就是构造DAGScheduler和TaskScheduler。构建TaskScheduler之后,TaskScheduler通过它对应的一个后台进程,去负责连接master,向master申请注册application,master接收到application注册的请求之后,会使用资源调度算法,在spark集群的worker上,为这个application启动多个Executor。executor启动之后会自己反向注册到TaskScheduler,Executor全部反向注册到Driver之后,Driver会结束SparkConctext初始化,继续执行我们自己的代码。
3、构建job及其划分
Spark代码每触发一次action就会创建一个job,DAGScheduler将Job划分成由Stage组成的DAG后,就根据Stage的具体类型来生成ShuffleMapTask和ResultTask,然后使用TaskSet对其进行封装,最后调用TaskScheduler的submitTasks方法提交具体的TaskSet。TaskScheduler把taskset里的每一个task提交到executor上执行。executor每接收到一个Task,都会用TaskRunner来封装task,然后从线程池里取出一个线程,执行这个task。TaskRunner把spark代码的算子或者函数拷贝、反序列化,然后执行task。
所以,整个spark应用程序的执行,就是stage分批次作为taskset提交到executor执行,每个task针对RDD的一个partition,执行我们定义的算子和函数,以此类推,直到所有的操作执行结束。
具体的细节算法,会在后续的文章中详细解读