文章目录
引语
当我们在Linux服务器上输入start-all的时候,Spark集群就被我们启动,紧接着就看到屏幕上打印了一行行的信息。那么start-all是怎么启动Spark集群的呢?在启动集群时又做了哪些事情呢?接下来这篇文章将结合源码的分析向大家详细展示Spark集群的启动流程。 该文章是以spark-1.3.1版本的源码来进行分析的,版本不同里面的源码也略有不同。
Spark集群启动流程图
首先来看看调用spark-all脚本时,集群启动的主要流程吧,总共分五个步骤。spark集群启动流程图如下:

启动流程描述
1、调用start-all脚本,启动Master服务,首先执行preStart,检查超时的Worker。
2、再执行receiver方法,不断接收其他Actor发送过来的请求。
3、调用start的时候,会解析slaves配置文件,决定在那几个节点启动Worker服务,在Worker启动的时候,执行preStart方法,向Master进行注册。
4、Master接收到Worker的注册信息后,开始持久化注册信息,并响应给Worker。
5、Worker接收到Master的响应信息,并开始向Master发送心跳。
源码详细分析部分
Master启动
1、调用Master中的main方法
1.1准备一些用于启动Master服务的配置信息
1.2创建actorSystem并生成actor(调用startSystemAndActor)
1.2.1 startSystemAndActor方法调用AkkaUtils的createActorSystem方法创建actorSystem
1.2.2 再调用actorSystem的actorOf方法调用并启动了属于Master的actor
2、调用preStart方法
preStart是生命周期方法,只会执行一次,主要用于初始化。
2.1 启动一个定时器,定时检查超时的Worker(60秒检查一次),定时器调用了CheckForWorkerTimeOut方法,并且过滤出超时的Worker。
2.1.1 CheckForWorkerTimeOut又调用了timeOutDeadWorkers()方法进行了超时Worker的过滤。
timeOutDeadWorkers()过滤超时Worker
(1)拿到当前的时间
(2)再把当前的时间-Worker的超时时间得到一个值,如果这个值(_.lastHeartbeat < currentTime - WORKER_TIMEOUT)大于当前Worker的最后一次心跳时间,则这个Worker就认为该Worker已经超时,然后把超时的Worker放到一个数组里。
(3)得到超时Worker的数组,进行遍历。如果Worker的状态不是Dead状态,就调用removeWorker从内存和磁盘当中移除该Worker。否则直接移除该Worker。
3、执行receiver方法(真正方法名receiveWithLogging(207行))。receiver方法,会不断地执行,不断接收其他actor发送过来的请求信息。
Worker启动
1、调用Worker的main方法
1.1 准备一些用于启动Worker服务的配置信息
1.2 创建actorSystem并生成actor(调用startSystemAndActor)
1.2.1 startSystemAndActor方法调用AkkaUtils的createActorSystem方法创建actorSystem。
1.2.3 再调用actorSystem的actorOf方法 调用并启动了属于Worker的actor
2、调用preStart方法
2.1 调用registerWithMaster()向所有Master进行注册
2.1.1 registerWithMaster()中调用tryRegisterAllMasters()方法尝试向所有Master进行注册(为什么要向所有的Master进行注册,因为刚开始不知道那个Master是active状态)
tryRegisterAllMasters()
1)遍历Master的URL
2)通过masterUrl获取Master的actor并把所有信息都封装到RegisterWorker这个类当中
3)通过异步无返回值的方式向Master发送注册信息
Master接收到Worker发送的注册信息
1、判断Master的状态,如果是StandBy状态,就什么都不做。
2、如果找到Id对应的WorkerInfo,证明已经注册过,就不需要注册了,提示Worker的ID重复(Duplicate worker ID)。
3、如果没有注册,且Master是active状态,就开始进行注册。
3.1 将注册信息进行封装到WorkerInfo类中
3.2 判断是否注册成功
3.2.1 调用registerWorker方法进行注册,注册成功则返回一个true,否则返回一个false
3.3 如果接收到一个true则表示已经注册
3.3.1 调用持久化引擎,把注册信息放到磁盘
3.3.2 向Worker响应注册成功的信息同把url发送给Worker
3.3.3 Master开始进行资源调度
Worker收到Master响应过来的信息
1、调用changeMaster方法,更新MasterURL,哪个机器是Active状态
2、启动一个定时器,调用SendHeartbeat方法,定时向Master发送心跳。
2.1 判断是否连接
2.2 如果是连接状态,就向Master发送心跳(发送workerId)
Master接收到Worker的心跳(workerId)
1、遍历WorkerInfo当中的所有Worker,跟传进来的workerId进行比对。
2、如果从Worker端传来的workerId在WorkerInfo当中存在,说明该Worker已经注册过,就更新该Worker的最后一次心跳时间为当前时间。
第二篇:Spark源码分析(二)—Spark提交任务流程及运行流程(spark-submit)