几个基本概念:
(1)job:包含多个task组成的并行计算,往往由action催生。 (2)stage:job的调度单位。 (3)task:被送到某个executor上的工作单元。 (4)taskSet:一组关联的,相互之间没有shuffle依赖关系的任务组成的任务集。
一个应用程序由一个driver program和多个job构成。一个job由多个stage组成。一个stage由多个没有shuffle关系的task组成。
Spark应用程序的运行架构:
(1)简单的说: 由driver向集群申请资源,集群分配资源,启动executor。driver将spark应用程序的代码和文件传送给executor。executor上运行task,运行完之后将结果返回给driver或者写入外界。 (2)复杂点说: 提交应用程序,构建sparkContext,构建DAG图,提交给scheduler进行解析,解析成一个个stage,提交给集群,由集群任务管理器进行调度,集群启动spark executor。driver把代码和文件传给executor。executor进行各种运算完成task任务。driver上的block tracker记录executor在各个节点上产生的数据块。task运行完之后,将数据写入HDFS上或者其他类型数据库里。 (3)全面点说: spark应用程序进行各种transformation的计算,最后通过action触发job。提交之后首先通过sparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAGScheduler进行解析,解析时是以shuffle为边界,反向解析,构建stage,stage之间也有依赖关系。这个过程就是对DAG图进行解析划分stage,并且计算出各个stage之间的依赖关系。然后将一个个TaskSet提交给底层调度器,在spark中是提交给taskScheduler处理,生成TaskSet manager,最后提交给executor进行计算,executor多线程计算,计算完反馈给TaskSetmanager,再反馈给taskScheduler,然后再反馈回DAGScheduler。全部运行完之后写入数据。 (4)更加深入理解:
应用程序提交后,触发action,构建sparkContext,构建DAG图,提交给DAGScheduler,构建stage,以stageSet方式提交给TaskScheduler,构建taskSet Manager,然后将task提交给executor运行。executor运行完task后,将完成信息提交给schedulerBackend,由它将任务完成的信息提交给TaskScheduler。TaskScheduler反馈信息给TaskSetManager,删除该task任务,执行下一个任务。同时TaskScheduler将完成的结果插入到成功队列里,加入之后返回加入成功的信息。TaskScheduler将任务处理成功的信息传给TaskSet Manager。全部任务完成后TaskSet Manager将结果反馈给DAGScheduler。如果属于resultTask,交给JobListener。如果不属于resultTask,保存结果。
附:在集群上运行Spark应用的详细过程
(1)用户通过 spark-submit 脚本提交应用。
(2)spark-submit 脚本启动驱动器程序,调用用户定义的 main() 方法。
(3)驱动器程序与集群管理器通信,申请资源以启动执行器节点。
(4)集群管理器为驱动器程序启动执行器节点。
(5)驱动器进程执行用户应用中的操作。根据程序中所定义的对RDD的转化操作和行动操作,驱动器节点把工作以任务的形式发送到执行器程序。
(6)任务在执行器程序中进行计算并保存结果。
(7)如果驱动器程序的 main() 方法退出,或者调用了 SparkContext.stop(),驱动器程序会终止执行器进程,并且通过集群管理器释放资源。