Spark的基本概念:
(1)Application:表示你的应用程序
(2)Driver:表示main()函数,创建SparkContext。由SparkContext负责与ClusterManager通信,进行资源的申请,任务的分配和监控等。程序执行完毕后关闭SparkContext
(3)Executor:某个Application运行在Worker节点上的一个进程,该进程负责运行某些task,并且负责将数据存在内存或者磁盘上。在Spark on Yarn模式下,其进程名称为 CoarseGrainedExecutor Backend,一个CoarseGrainedExecutor Backend进程有且仅有一个executor对象,它负责将Task包装成taskRunner,并从线程池中抽取出一个空闲线程运行Task,这样,每个CoarseGrainedExecutorBackend能并行运行Task的数据就取决于分配给它的CPU的个数。
(4)Worker:集群中可以运行Application代码的节点。在Standalone模式中指的是通过slave文件配置的worker节点,在Spark on Yarn模式中指的就是NodeManager节点。
(5)Task:在Executor进程中执行任务的工作单元,多个Task组成一个Stage
(6)Job:包含多个Task组成的并行计算,是由Action行为触发的
(7)Stage:每个Job会被拆分很多组Task,作为一个TaskSet,其名称为Stage
(8)DAGScheduler:根据Job构建基于Stage的DAG,并提交Stage给TaskScheduler,其划分Stage的依据是RDD之间的依赖关系
(9)TaskScheduler:将TaskSet提交给Worker(集群)运行,每个Executor运行什么Task就是在此处分配的。
Spark的执行流程:
Spark在进行transformation计算的时候,不会触发Job ,只有执行action操作的时候,才会触发Job,在Driver中SparkContext根据RDD之间的依赖关系创建出DAG有向无环图,DAGScheduler负责解析这个图,解析时是以Shuffle为边界,反向解析,构建stage。将多个任务根据依赖关系划分为不同的Stage,将每个Stage的Taste Set 提交给TaskScheduler去执行,任务会在Executor进程的多个Task线程上执行,完成Task任务后 将结果信息提交到ExecutorBackend中 他会将信息提交给TaskScheduler。
TaskScheduler接到消息后通知TaskManager,移除该Task任务,开始执行下一个任务。TaskScheduler同时会将信息同步到TaskSet Manager中一份,全部任务执行完毕后TaskSet Manager将结果反馈给DAGScheduler,如果属于ResultTask 会交给JobListener。否则话全部任务执行完毕后写入数据。
Driver运行在Worker:
(1)客户端提交作业给Master
(2)Master让一个Worker启动Driver,即SchedulerBackend。Worker创建一个DriverRunner线程,DriverRunner启动SchedulerBackend线程。
(3)另外Master还会让其余Worker启动Executor,即ExecutorBackend。Worker创建一个ExecutorRunner线程,ExecutorRunner会启动ExecutorBackend进程。
(4)ExecutorBackend启动后会向Driver的SchedulerBackend注册,SchedulerBackend进程中包含DAGScheduler,ExecutorBackend向SchedulerBackend汇报的时候把TaskScheduler中的Task调度到ExecutorBackend执行。
(5)所有stage都完成后作业结束
Spark运行架构的特点:
每个Application获取专属的Executor进程,该进程在Application期间一直驻留,并以多线程方式运行tasks。这种Application隔离机制有其优势,无论是从调度角度看(每个Driver调度它自己的任务),还是从运行角度看(来自不同Application的Task运行在不同的JVM中)。当前,这也意味着SparkApplication不能跨应用程序共享数据,除非将数据写入到外部存储系统。
提交SparkContext的Client应该靠近Worker节点(运行Executor)的节点,最好是在同一个Rack里,因为SparkApplication运行过程中SparkContext和Executor之间有大量的信息交换,如果想在远程集群中运行,最好使用RPC将SparkContext提交给集群