图片

  • 一. 概念
  • 二. 作业调度流程
  • 三. Spark运行架构具有以下特点
  • 四. spark 详细运行过程
  • 1)
  • 2)
  • 3)


一. 概念

一个Application由一个Driver和若干个Job构成,
一个Job由多个Stage构成,
一个Stage由多个没有Shuffle关系的Task组成
(多个RDD算子操作)

stage:宽窄依赖划分

当执行一个Application时,Driver会向集群管理器申请资源,启动Executor,并向Executor发送应用程序代码和文件,然后在Executor上执行Task,运行结束后,执行结果会返回给Driver,或者写到HDFS或者其他数据库中.

二. 作业调度流程

spark的standalone和yarn_初始化

  1. 构建Spark Application的运行环境(启动SparkContext),SparkContext向资源管理器(可以是Standalone、Mesos或YARN)注册并申请运行Executor资源;
  2. 资源管理器分配Executor资源并启动StandaloneExecutorBackend,Executor运行情况将随着心跳发送到资源管理器上;
  3. SparkContext构建成DAG图,将DAG图分解成Stage,并把Taskset发送给Task Scheduler。Executor向SparkContext申请Task
  4. Task Scheduler将Task发放给Executor运行同时SparkContext将应用程序代码发放给Executor。
  5. Task在Executor上运行,运行完毕释放所有资源。

三. Spark运行架构具有以下特点

(1)每个Application获取专属的executor进程,该进程在Application期间一直驻留,并以多线程方式运行tasks。这种Application隔离机制有其优势的,无论是从调度角度看(每个Driver调度它自己的任务),还是从运行角度看(来自不同Application的Task运行在不同的JVM中)。当然,这也意味着Spark Application不能跨应用程序共享数据,除非将数据写入到外部存储系统。
(2)Spark与资源管理器无关,只要能够获取executor进程,并能保持相互通信就可以了。
(3)提交SparkContext的Client应该靠近Worker节点(运行Executor的节点),最好是在同一个Rack里,因为Spark Application运行过程中SparkContext和Executor之间有大量的信息交换;如果想在远程集群中运行,最好使用RPC将SparkContext提交给集群,不要远离Worker运行SparkContext。
(4)Task采用了数据本地性和推测执行的优化机制。

四. spark 详细运行过程

1)

spark的standalone和yarn_spark 作业调度_02

  1. Driver程序的代码运行到action操作,触发了SparkContext的runJob方法。
  2. SparkContext调用DAGScheduler的runJob函数。
  3. DAGScheduler把Job划分stage,然后把stage转化为相应的Tasks,把Tasks交给TaskScheduler。
  4. 通过TaskScheduler把Tasks添加到任务队列当中,交给SchedulerBackend进行资源分配和任务调度, 每个tasks就有多个Threads, 在worker中process(运行)。
  5. 调度器给Task分配执行Executor,ExecutorBackend负责执行Task。Executor执行结束后,回传给Driver,把执行结果存储到本地或hdfs上

2)

spark的standalone和yarn_作业调度_03

  1. Driver程序的代码运行到action操作,触发了SparkContext的runJob方法。
  2. SparkContext调用DAGScheduler的runJob函数。
  3. DAGScheduler把Job划分stage,然后 DAGScheduler把Job提交stage,DAGScheduler把stage转化为相应的TaskSet,把TaskSet交给TaskScheduler。
  4. 通过TaskScheduler把Tasks添加到任务队列当中,并把计算任务提交给调度器SchedulableBuilder
  5. 调度器SchedulableBuilder调度任务TaskScheduler
  6. TaskScheduler为task分配任务资源,并提交tasks给SchedulerBackend
  7. 交给SchedulerBackend进行资源分配和任务调度, 将任务提交到Executor上运行, 在Executor(worker)中process(运行)。
  8. 调度器给Task分配执行Executor,ExecutorBackend负责执行Task。Executor执行结束后,回传给Driver,把执行结果存储到本地或hdfs上

3)

spark的standalone和yarn_初始化_04

  1. 我们提交一个任务,任务就叫Application
    初始化程序的入口SparkContext,
      1.1 初始化DAG Scheduler
      1.2 初始化Task Scheduler
  2. Task Scheduler中的ClientEndpoint向master去进行注册并申请资源(CPU Core和Memory)
  3. Master根据SparkContext的资源申请要求和Worker心跳周期内报告的信息决定在哪个Worker上分配资源,然后在该Worker上获取资源,然后启动StandaloneExecutorBackend;顺便初始化好了一个线程池,通知worker启动Executor
  4. StandaloneExecutorBackend向Driver(SparkContext)注册,这样Driver就知道哪些Executor为他进行服务了。
      到这个时候其实我们的初始化过程基本完成了,我们开始执行transformation的代码,但是代码并不会真正的运行,直到我们遇到一个action操作。生产一个job任务,进行stage的划分
  5. 发送任务到Executor进行执行
    5.1 SparkContext将Applicaiton代码发送给Standalone ExecutorBackend;并且SparkContext解析Applicaiton代码,构建DAG图,并提交给DAG Scheduler分解成Stage(当碰到Action操作时,就会催生Job;每个Job中含有1个或多个Stage,Stage一般在获取外部数据和shuffle之前产生)。
    5.2 将Stage(或者称为TaskSet)提交给Task Scheduler。Task Scheduler负责将Task分配到相应的Worker,最后提交给StandaloneExecutorBackend执行;
    5.3 对task进行序列化,并根据task的分配算法,分配task
    5.4 对接收过来的task进行反序列化,把task封装成一个线程
  6. 开始执行Task,并向SparkContext报告,反馈任务状态给Driver
  7. APPlication程序运行完毕后,回收资源