Yarn-Cluster模式
- 执行脚本提交任务,实际是启动一个 SparkSubmit 的 JVM 进程;
- SparkSubmit 类中的 main方法反射调用Client的main方法;
- Client创建Yarn客户端,然后向Yarn发送执行指令:bin/java ApplicationMaster;
- Yarn框架收到指令后会在指定的NM中启动ApplicationMaster;
- ApplicationMaster启动Driver线程,执行用户的作业;
- AM向RM注册,申请资源;
- 获取资源后AM向NM发送指令:bin/java CoarseGrainedExecutorBacken;
- 启动ExecutorBackend, 并向driver注册.
- 注册成功后, ExecutorBackend会创建一个Executor对象.
- Driver会给ExecutorBackend分配任务, 并监控任务的执行.
- 注意:
• SparkSubmit、ApplicationMaster和CoarseGrainedExecutorBacken是独立的进程;
• Client和Driver是独立的线程;
• Executor是一个对象。
Sparksubmit阶段
- 首先运行bin/spark-submit --master yarn --deploy-mode
cluster
,在bin/SparkSubmit找到SparkSubmit类,运行main方法, - 然后进入submit方法里,准备好提交环境(prepareSubmitEnvironment(args)),得到““org.apache.spark.deploy.yarn.Client””,
- 运行runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose),反射Clinet类运行main方法
- 在Client的main方法里调用run(),运行submitApplication()
- 在submitApplication方法里初始化并启动yarn(yarnClient.start()),并且创建一个AM程序( yarnClient.createApplication())并提交到RM上
ApplicationMaster阶段 - 在AM的main方法里运行 ApplicationMaster 的 run 方法(master.run())
- 在run方法里runDriver(securityMgr),启动一个子线程来执行用户类提交的 main 方法,并且讲此线程名设置为Driver,
- 在runDriver的主线程里则注册AM到RM(registerAM),RM分配资源(handleAllocatedContainers)然后启动分配到的容器(runAllocatedContainers)
CoarseGrainedExecutorBackend阶段 - 运行main方法, 启动 CoarseGrainedExecutorBackend( run),然后运行onstart方法, // 向驱动注册 Executor (ref.ask)
- Driver端的CoarseGrainedSchedulerBackend类的receiveAndReply方法收到后返回RegisteredExecutor(executorRef.send(RegisteredExecutor))
- CoarseGrainedExecutorBackend端的receive方法接收到RegisteredExecutor创建 Executor 对象( new Executor)
- Executor 全部创建完成后Driver开始执行main方法,遇到Action算子时会触发一个job,在一个job里会根据宽依赖进行划分stage,每一个stage生成一个taskSet,之后将task分配到各个Executor
Yarn-Client模式
- 执行脚本提交任务,实际是启动一个SparkSubmit的 JVM 进程;
- SparkSubmit伴生对象中的main方法反射调用用户代码的main方法;
- 启动Driver线程,执行用户的作业,并创建ScheduleBackend;
- YarnClientSchedulerBackend向RM发送指令:bin/java ExecutorLauncher;
- Yarn框架收到指令后会在指定的NM中启动ExecutorLauncher(实际上还是调用ApplicationMaster的main方法);
object ExecutorLauncher {
def main(args: Array[String]): Unit = {
ApplicationMaster.main(args)
}
}
- AM向RM注册,申请资源;
- 获取资源后AM向NM发送指令:bin/java CoarseGrainedExecutorBacken;
- 后面和cluster模式一致
注意:
- SparkSubmit、ExecutorLauncher和CoarseGrainedExecutorBacken是独立的进程;
- driver不是一个子线程,而是直接运行在SparkSubmit进程的main线程中, 所以sparkSubmit进程不能退出.
SparkSubmit阶段
- 当用户使用了bin/spark-submit --master yarn --deploy-mode
client
,在bin/spark-submit脚本的全类名,运行SparSubmit的main方法, - 进入main方法里,然后在进入submit方法,通过准备环境方法(prepareSubmitEnvironment)获取到childMainClass=用户提交的类,
- 接着在submit方法里的runMain里通过反射调用用户提交类的main方法,
- 通过实例化SparkContext,创建TaskScheduler(SparkContext.createTaskScheduler),在创建TaskScheduler方法里创建YarnClientSchedulerBackend(cm.createSchedulerBackend)
- 在SparkContext类启动YarnScheduler(_taskScheduler.start())
- 在YarnClientSchedulerBackend的start方法里使用 Client 提交应用bindToYarn(client.submitApplication(), None)
- -接着在Client类里运行submitApplication方法,在createContainerLaunchContext方法里反射调用(“org.apache.spark.deploy.yarn.ExecutorLauncher”),然后提交应用到RM(yarnClient.submitApplication(appContext))
ExecutorLauncher阶段
- 启动ExecutorLauncher,在main方法里执行 ApplicationMaster.main(args)
- 执行ApplicationMaster 的main方法, 运行 ApplicationMaster 的 run 方法
- 在run方法调用 runExecutorLauncher(securityMgr),在方法里执行registerAM。