- Spark支持3种集群管理器,分别为:
Standalone:独立模式是park原生的集群管理器,自带完整服务
Hadoop Yarn:统一的资源管理机制,在桑面运行多套框架(生产环境常用),根据 Driver 在集群中的位置不同,分为 yarn client 和 yarn cluster;
Apache Mesos:一个强大的分布式资源管理框架,它允许多种不同的框架部署在其上,包括yarn
- 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是一个对象。
- Yarn-Client模式运行机制
- 执行脚本提交任务,实际是启动一个SparkSubmit的 JVM 进程;
- SparkSubmit伴生对象中的main() 方法反射调用用户代码的main()方法;
- 启动Driver现成,执行用户的作业,并创建ScheduleBackend;
- YarnClientSchedulerBackend向RM发送指令:bin/java ExecutorLauncher;
- Yarn框架收到指令后会在指定的NM中启动ExecutorLauncher(实际上还是调用ApplicationMaster的main方法);
- AM向RM注册,申请资源;
- 获取资源后AM向NM发送指令::bin/java CoarseGrainedExecutorBacken;
- 后面和cluster模式一致;
//第五步源码验证
- 注意:
- SparkSubmit、ExecutorLauncher和CoarseGrainedExecutorBacken是独立的进程;
- driver不是一个子线程,而是直接运行在SparkSubmit进程的main线程中, 所以sparkSubmit进程不能退出。
- Yarn-Cluster模式运行机制源码分析
启动下面的代码
bin
yarn 会按照下面的顺序依次启动了 3 个进程:
SparkSubmit
ApplicationMaster
CoarseGrainedExecutorB ackend
- bin/spark-submit 启动脚本分析
启动类org.apache.spark.deploy.SparkSubmit
exec "${SPARK_HOME}"/bin/spark-class org.apache.spark.deploy.SparkSubmit "$@"
- /bin/spark-class
exec "${CMD[@]}"
- 最终启动类
/
- org.apache.spark.deploy.SparkSubmit 源码分析
- SparkSubmit伴生对象
main()方法
def
submit()方法
/**
prepareSubmitEnvironment 方法
// In yarn-cluster mode, use yarn.Client as a wrapper around the user class
doRunMain 方法
def
runMain 方法
/**
- org.apache.spark.deploy.yarn.Client源码分析
main()方法
def
Client.run方法
def
client.submitApplication 方法
/**
createContainerLaunchContext方法
private
-----SparkSubmit进程启动完毕.-----
- org.apache.spark.deploy.yarn.ApplicationMaster 源码分析
ApplicationMaster伴生对象的main方法
def
ApplicationMaster 伴生类的 run方法
final
runDriver 方法
private
startUserApplication 方法
private
registerAM 方法
private
allocator.allocateResources() 方法
/**
handleAllocatedContainers方法
/**
runAllocatedContainers 方法
/**
ExecutorRunnable.run方法
def
ExecutorRunnable.startContainer()
def
ExecutorRunnable.prepareCommand 方法
private
-----ApplicationMaster 进程启动完毕-----
- org.apache.spark.executor.CoarseGrainedExecutorBackend 源码分析
CoarseGrainedExecutorBackend伴生对象main()方法
def
run 方法
/**
- CoarseGrainedExecutorBackend伴生类
继承自: ThreadSafeRpcEndpoint 是一个RpcEndpoint
查看生命周期方法
onStart 方法
连接到 Driver, 并向 Driver注册Executor
override
Driver端的CoarseGrainedSchedulerBackend.DriverEndPoint 的 receiveAndReply 方法
override
Eexcutor端的CoarseGrainedExecutorBackend的receive方法
override
-----Executor 创建完毕-----
- 总结
- Yarn-Client模式运行机制源码分析
执行下面的代码:
bin
启动类:
/
依次启动 3 个不同的进程:
SparkSubmit
ExecutorLauncher
CoarseGrainedExecutorBackend
- client模式下直接运行用户的主类
prepareSubmitEnvironment 方法
/*
然后不会创建ApplicationMaster, 而是直接执行用户类的main方法,然后开始实例化 SparkContext
实例化SparkContext
val
SparkContext.createTaskScheduler 方法 关键代码:
private
YarnClusterManager 类
private
_taskScheduler.start()
YarnClientSchedulerBackend 的 start 方法
/**
- org.apache.spark.deploy.yarn.Client源码再分析
submitApplication 方法
yarnClient.submitApplication(appContext)
ExecutorLauncher 类
yarnClient 提交应用的时候, 把要执行的主类(ExecutorLauncher)封装到配置中. 所以不是启动ApplicationMaster, 而是启动ExecutorLauncher
// createContainerLaunchContext()
- ApplicationMaster源码再分析
run 方法
final
runExecutorLauncher
private
后面的流程就和yarn-cluster模式一样了. 不再赘述
- 总结:
- Standalone模式运行机制
- Standalone 集群有 2 个重要组成部分,分别是:
1. Master(RM):是一个进程,主要负责资源的调度和分配,并进行集群的监控等职责, 一个是用自己的内存存储 RDD 的某个或某些 partition,另一个是启动其他进程和线程(Executor),对 RDD 上的 partition 进行并行的处理和计算。
根据 driver的位置不同, 也分 2 种:
- Standalone-Cluster模式
在Standalone Cluster模式下,任务提交后,Master会找到一个 Worker 启动Driver。
Driver启动后向Master注册应用程序,Master根据 submit 脚本的资源需求找到内部资源至少可以启动一个Executor 的所有Worker,然后在这些 Worker之间分配Executor,Worker上的Executor启动后会向Driver反向注册,所有的 Executor 注册完成后,Driver 开始执行main函数,之后执行到Action算子时,开始划分 tage,每个 Stage 生成对应的taskSet,之后将 Task 分发到各个 Executor 上执行。
- Standalone-Client模式
在 Standalone Client 模式下,Driver 在任务提交的本地机器上运行。
Driver启动后向 Master 注册应用程序,Master 根据 submit 脚本的资源需求找到内部资源至少可以启动一个Executor 的所有 Worker,然后在这些 Worker 之间分配 Executor,Worker 上的 Executor 启动后会向Driver反向注册,所有的Executor注册完成后,Driver 开始执行main函数,之后执行到Action算子时,开始划分Stage,每个Stage生成对应的TaskSet,之后将Task分发到各个Executor上执行。
————结束————
关于spark各组件底层如何通信的请移步历史文章看上一期,底层各组件通信源码