1. spark中的Job
- 一个Spark应用包含一个驱动进程(driver process,在这个进程中写Spark的逻辑代码) 和多个执行器进程(executor process,跨越集群中的多个节点)。Spark 程序自己是运行在驱动节点, 然后发送指令到执行器节点。
- 一个Spark集群可以同时运行多个Spark应用, 这些应用是由集群管理器(cluster manager)来调度。
- Spark应用可以并发的运行多个job, job对应着给定的应用内的在RDD上的每个 action操作。
1. spark应用
- 一个Spark应用可以包含多个Spark job, Spark job是在驱动程序中由SparkContext 来定义的。
- 当启动一个 SparkContext 的时候, 就开启了一个 Spark 应用。 一个驱动程序被启动了, 多个执行器在集群中的多个工作节点(worker nodes)也被启动了。 一个执行器就是一个 JVM, 一个执行器不能跨越多个节点, 但是一个节点可以包括多个执行器。
- 一个 RDD 会跨多个执行器被并行计算. 每个执行器可以有这个 RDD 的多个分区, 但是一个分区不能跨越多个执行器.
2. spark job任务划分
-
由于Spark的懒执行, 在驱动程序调用一个action之前, Spark 应用不会做任何事情,针对每个action,Spark 调度器就创建一个执行图(execution graph)和启动一个 Spark job。
-
每个 job 由多个stages 组成, 这些 stages 就是实现最终的 RDD 所需的数据转换的步骤。一个宽依赖划分一个stage。每个 stage 由多个 tasks 来组成, 这些 tasks 就表示每个并行计算, 并且会在多个执行器上执行。
2. stage任务划分
- DAG有向无环图
DAG(Directed Acyclic Graph)有向无环图是由点和线组成的拓扑图形,该图形具有方向,
不会闭环。原始的RDD通过一系列的转换就形成了DAG,根据RDD之间的依赖关系的不同将DAG划分成不同的Stage,对于窄依赖,partition的转换处理在Stage中完成计算。对于宽依赖,由于有Shuffle的存在,只能在parent RDD处理完成后,才能开始接下来的计算,因此宽依赖是划分Stage的依据。例如,DAG记录了RDD的转换过程和任务的阶段。 - RDD任务切分中间分为:Application、Job、Stage和Task
- (1)Application:初始化一个SparkContext即生成一个Application;
- (2)Job:一个Action算子就会生成一个Job;
- (3)Stage:Stage等于宽依赖的个数加1;
- (4)Task:一个Stage阶段中,最后一个RDD的分区个数就是Task的个数。 注意:Application->Job->Stage->Task每一层都是1对n的关系。
3. 概念小结
-
集群(Standalone|Yarn)
- 一个Spark集群可以同时运行多个Spark应用
-
应用
- 我们所编写的完成某些功能的程序
- 一个应用可以并发的运行多个Job
-
Job
- Job对应着我们应用中的行动算子,每次执行一个行动算子,都会提交一个Job
- 一个Job由多个Stage组成
-
Stage
- 一个宽依赖做一次阶段的划分
- 阶段的个数 = 宽依赖个数 + 1
- 一个Stage由多个Task组成
-
Task
- 每一个阶段最后一个RDD的分区数,就是当前阶段的Task个数
3. stage任务划分源码
粗略版源码
-
开启任务,提交作业
-
划分stage,并提交stage
-
创建stage
-
提交Task