SparkContext源码分析
SparkContext初始化的时候会创建taskScheduler
进入createTaskScheduler方法
有spark-submit的三种提交模式:
这是我们常用的standdlone提交模式,在这种模式下会创建一个TaskSchedulerImpl,也会创建一个SparkDeploySchedulerBackend()并将scheduler传入进去,然后通过initialize()方法初始化
进入TaskScheduleImpl
1,底层通过操作一个SchedulerBackend,针对不同的cluster,调度task
2,它也可以通过使用一个LocalBackend,并将isLocal参数设置为true,来在本地模式下工作
3,它负责处理一些通用的逻辑,比如说决定多个job的调度顺序,启动推测任务执行
4,客户端首先应该想调用它的initialize() and start()方法,然后通过runTasks()方法提交task sets
进入scheduler.initialize(backend)的初始化代码,创建了一个调度池rootPool,会匹配到调度规则FIFO或FAIR,然后通过schedulableBuilder创建调度池
完成以上操作之后会调用taskScheduler.start()方法,start方法在TaskScheduleImpl类中,其最主要的是将底层的SparkDeploySchedulerBackend类中的start()方法调用
在SparkDeploySchedulerBackend类中的start()方法中,会创建一个ApplicationDescription()类,它就代表了当前执行的application的一些情况,包括application最大需要多少cpu,core,每个slave上需要多少内存
进入这个类,在这个ApplicationDescription类中会初始化一些参数
在ApplicationDescription类创建完了之后会在创建一个AppClient类,并将appDesc传入进去
进入AppClient类
1,这是一个接口,它负责为application与spark集群进行通信,它会接收一个spark master的url,以及一个ApplicationDescription,和一个集群时间的监听器,以及各种事件发生时监听器
进入start()方法,发现它通过ak来创建一个ClientActor
ClientActor是一个内部类,它会调用registerWithMaster()方法
在registerWithMaster()方法内它又会调用tryRegisterAllMasters()方法,tryRegisterAllMasters()方法它回去连接Master,然后将appDescription封装在RegisterApplication里面,发送到master去进行Application的注册
以上是SparkContext初始化的时候会构造TaskScheduler的源代码剖析
接下来是SparkContext初始化构造DAGScheduler的源代码剖析
SparkContext在初始化的时候不仅仅构造了TaskScheduler也构造了DAGScheduler
进入DAGScheduler
这个类实现了面向stage的调度机制的高层次的调度层。它会为每个job计算一个stage的DAG(有向无环图),追踪RDD和stage的输出时候被物化了(写入磁盘或内存),并寻找一个最小(最优)调度机制来运行job。
它会将stage作为tasksets提交到底层的TaskSchedulerImpl上,来在集群上运行task
除了处理stage的DAG,它还负责决定运行每个task的最佳位置,基于当前的缓存状态,将这些最佳位置提交给底层的TaskSchedulerImpl。此外,他会处理由于shuffle输出文件丢失导致的失败,在这种情况下,旧的stage可能会被重新提交。一个stage内部的失败,如果不是由于shuffle文件丢失导致的,会被TaskSecheduler处理,它会多次重试每一个task,知道最后,实在不行了,才会去取消整个stage。
接下来是SparkUI
在提交任务的是会有一个web界面来查看当前运行任务的状态,通过默认端口4040可以查看,其底层是通过jetty启动一个web的服务器,为我们提供了一个web的监控页面