SparkContext 是整个 spark 程序通往集群的唯一通道, 他是程序的起点, 也是程序的终点.
我们的每一个 spark 个程序都需要先创建 SparkContext, 接着调用 SparkContext 的方法, 比如说 sc.textFile(filepath), 程序最后也会调用 sc.stop() 来退出.
让我们来一起看下 SparkContext 里面到底是如何实现的吧!
1 SparkContext 内的三大核心对象: DAGScheduler,TaskScheduler,SchedulerBackend
DAGScheduler: 面向 Stage 调度机制的高层调度器, 会为每个 job 计算一个 Stage 的 DAG(有向无环图). 追踪 RDD 和 Stage 的输出是否物化 (写磁盘或内存), 并且执行一个最优的调度机制来执行. 将 stage 作为 tasksets 提交到底层的 TaskScheduler 并在集群上运行. DAGScheduler 监控作业运行调度的过程, 如果某个阶段运行失败, 会重新提交提交该调度阶段.
TaskScheduler: 是一个接口, 底层调度器. 会根据 ClusterManager 的不同有不同的实现, 在 Standalone 模式下的实现为 TaskSchedulerImpl. 接收 DAGScheduler 发过来的任务集, 并以任务的形式分发到集群 worker 节点的 Executor 中去运行, 任务失败 TaskScheduler 负责重试. 如果 TaskScheduler 发现某个任务一直没运行完, 可能会启动同样的任务去运行一个任务, 结果选取早运行完的那个任务的 (预测执行).
SchedulerBackend: 是一个接口, 根据 ClusterManager 的不同会有不同的实现, Standalone 模式下是 StandaloneSchedulerBackend(2.3 版本, 1.x 版本是 SparkDeploySchedulerBackend) 底层接受 TaskSchedulerImpl 的控制, 实际负责 Master 的注册和 Tasks 发送到 Executor 等操作.
2.1 图示 SparkContext 实例化过程
如下图所示, 我们看下 SparkContext 在实例化过程中, 会创建多少核心实例来完成整个应用程序的注册.

2.2 时序图

3 主要内容描述
- createTaskScheduler
- createSchedulerBackend
SchedulerBackend 的 initialize 初始化构造默认 FIFO 调度吃
new DAGScheduler
创建 StandaloneAppClient 与 spark 集群通信
创建 AppClient,ClientEndPoint(向 master 注册)
发消息 RegisterApplication
ClientEndpoint.receive() 函数接收 master 的回复消息
4 通过源码看 SparkContext 实例化过程 (Standalone 模式)
scala 中不在方法里的成员都会被实例化, 开始最关键的方法是 createTaskScheduler, 它是位于 SparkContext 的 构造函数中, 当它实例化时会直接被调用.
createTaskScheduler 创建了 TaskSchedulerImpl 并通过 StandaloneSchedulerBackend 对其进行初始化.
createTaskScheduler 返回 scheduleBackend 和 TaskScheduler, 然后又基于 TaskScheduler 构造 DAGScheduler.
SparkContext 调用 createTaskScheduler 方法, 返回 SchedulerBackend 和 TaskScheduler.

下 createTaskScheduler 方法内部: 根据不同的 master url 创建不同的 TaskScheduler 实现和不同的 SchedulerBackend 实现. master url 就是创建 SparkContext 的时候传的, 例如下面的 local:
- val conf = new SparkConf().setAppName("TestApp").setMaster("local")
- val sc = new SparkContext(conf)

taskSchedulerImpl 的初始化方法, 创建一个默认 FIFO 的调度池:

taskSchedulerImpl 初始化后, 随即为其设置 DAGScheduler, 然后调用其 start() 方法:

在 taskSchedulerImpl 的 start() 方法中再调用 backend(StandaloneSchedulerBackend) 的 start() 方法, 其中最重要的就是创建 ApplicationDescription 和 AppClient

创建 ApplicationDescription 和 AppClient

ApplicationDescription 存放当前应用程序信息, name,cores,memory 等.
AppClient 是 Application 与 Spark 通信的组件. 在 appClient.start() 的时候会创建内部类 ClientEndPoint

clientEndPoint 注册 master.

注册的时候会从线程池中拿出一个线程并且会带上 APPDescription 中的作业信息.

ClientEndpoint.receive 接收 master 返回的消息, 根据不同的返回消息做不同的操作.

SparkContext.DAGScheduler

创建 SparkUI

来源: https://www.cnblogs.com/wangtcc/p/da-huaSpark-6yuan-ma-zhiSparkContext-yuan-li-pou-x.html