Spark

Spark的局部内容和之前Spark系列重合,然而有些细节之前没有深刻。

Master启动

基于高可用的思考,Master会启动多个,然而只能有一个Master是提供服务的(ALIVE状态),其余Master都是STANDBY状态。

zookeeper集群的左右,一个是用来选举,另外一个是保留长久化Application、Driver、Executor的信息,便于复原。

Worker启动

Worker在启动的时候,就会向Master进行注册,注册时须要上传workid,host,端口以及cup外围数,内存大小。

因为Master是高可用的,所以刚开始Worker并不知道ALIVE节点是哪个,于是他就会把注册申请发送给每一个Master节点。

Worker只有注册胜利,才会被Master调用,所以为了保障注册胜利,Worker会进行一直的尝试。

一共尝试的次数是16次,为了防止所有的Worker同一时间发送心跳,给Master造成压力,所以发送心跳的间隔时间是随机的。

后面6次的心跳间隔时间是5~15s之间,前面10次的心跳间隔时间是30~90s之间。

如果在这16次内注册胜利,那就会勾销尝试。如果16次都没胜利,那这个Worker也没必要启动了,间接退出Worker过程。

这里重试的和刚开始注册的时候,有些不同。有可能因为某些起因导致重试,然而这个时候Worker是有Master的ALIVE节点信息,那Worker注册的时候,就间接往ALIVE节点注册就好了,不必每个Master都发送注册申请。

Master接管注册时,会看看本人是不是ALIVE节点,如果是STANDBY节点,那间接跟Worker说我是STANDBY节点,Worker晓得他是STANDBY节点,就不做任何解决。

而后Master就会看这个Worker是否注册过了(依据worker注册提供的workid),如果注册过了,就跟Worker说,注册失败了。

Worker接管到注册失败的信息,就会看看我有木有注册胜利啊(注册胜利会有变量保留),如果注册胜利,就疏忽这条音讯,晓得本人是反复注册。

如果发现自己没注册胜利,Master也说没注册胜利,那就是没注册胜利,所以退出Worker过程。

如果既不是STANDBY节点,Worker也没注册过,那就保留Worker的相应的信息,进行长久化,而后告知Worker曾经注册胜利。

Worker接管到胜利后,就会把变量更改为注册胜利(下面判断有用到),而后记录Master的地址(前面申请间接发这个地址了),勾销注册的重试工作(曾经胜利了就不须要再尝试注册了)。

最初会发状态给Master,因为刚开始注册,Worker中并没有Driver和Executor,所以Master不会解决。

Master如何晓得Worker存活

Worker注册胜利后,还有一个十分重要的事件,就是发送心跳,维持状态。发送心跳的时候,间接发送workerid就好。

Master接管申请后,先看看是否注册过,如果没有注册过,就会让Worker从新注册,就会反复下面的注册流程。如果注册过,就批改Worker最初的心跳工夫。

Master会有一个每隔60s的定时工作,对超过60s没有发送的Worker进行解决,会把这个Worker标记为DEAD状态,并移除其余相干内存(idToWorker用于映射workerid和Worker的关系,addressToWorker用于映射地址和Worker的关系)。

如果Worker曾经是DEAD状态了,那超过960s就把Worker信息也移除。

比方60s没发心跳,此时Master会移除相干内容,而后在960s内,Worker重启后进行注册,那就会把Worker中为DEAD状态的Worker删除,再从新加新的Worker信息。

Driver启动

Driver在启动后须要向Master注册Application信息,和Worker注册Master一样,Driver也不晓得哪个是ALIVE节点,所以他也向所有的Master进行注册。

注册信息包含Application的名称,Application须要的最大内核数,每个Executor所须要的内存大小,每个Executor所需的内核数,执行Executor的命令等信息。

这里的注册也有重试次数,最大重试3次,每次距离20s,注册胜利后,就会勾销重试。

Master收到申请后,如果是STANDBY节点,那不做解决,也不回复任何信息(这个和Worker注册不一样,Wokrer那边回回复信息,然而Worker不解决)。

如果不是STANDBY节点,那就会把Application信息保留内存中,并做长久化。

接着就会给Driver发送曾经注册胜利的音讯,Driver接管到音讯,就会记录Master的信息,以及外部标识曾经注册胜利,不须要再重试。

Master如何晓得Driver存活

Driver和Master之间并没有心跳,不像Worker会定时发送心跳,Master依据心跳移除过期的Worker,那Master怎么晓得Driver是否退出呢?

第一种形式是Driver被动告知Master,第二种形式是Driver不失常退出,Master一旦监听到Driver退出了。这两种形式都会勾销Application的注册。

Master接管到勾销注册Application的音讯后,就会移除缓存的Application及Application相干的Driver信息。

对于Driver,有可能还存在运行的Executor,就会发消息给Driver,让他杀死Executor,Driver收到音讯后就会进行Application。

对应Worker,Master会群发给所有的Worker,告知这个Application已实现,Worker收到音讯后,会清理Driver的临时文件。

最初把Application的信息长久化,并且告知其余Worker这个Application已实现。

Executor启动

Master在资源调度的时候,会让Worker启动Executor。

Worker接管到音讯后,会判断是否是STANDBY节点的Master发送的音讯,如果不是则疏忽。

如果是,Worker就会创立一个线程,用来启动一个Executor的过程,启动Executor的过程后会回复Master说Executor曾经启动胜利。

Master晓得Executor启动胜利,也会告知Driver,你的Executor我曾经帮你启动了。因为Executor并没有完结,Driver并没有做其余解决。

Executor启动后,就会向Driver进行注册,Driver先判断是否曾经注册过或者在黑名单里,如果是,返回失败,如果不是,则保留这个Executor的信息,并告知Executor曾经注册胜利。

Driver在Executor注册时,还做了一件事,就是把注册信息发送给事件总线。Driver里还有有一个心跳接收器,用于治理Executor状态的。

这个心跳接收器会对总线的事件进行监听,当发现有Executor新增的时候,就会记录这个Executor的id和工夫。

Worker如何晓得Executor存活

Worker创立线程用来启动Executor过程的时候,这个线程创立完并不会间接退出,而是始终期待获取Executor过程的退出状态。

获取后就会把状态发送给Worker,Worker再把状态转发给Master,并更改本身的内存、CPU信息。

Master发现Executor执行完了(不论失败还是胜利),就会更新内存信息,并且把状态转发给Driver。

Driver收到状态后,发现Executor执行完了,会发移除Executor的事件给事件总线。

心跳接收器会对总线的事件进行监听,当发现有Executor移除的时候,就会移除Executor。

Executor如何晓得Worker存活

Executor有一个WorkerWatcher,当Worker过程退出、连贯断开、网络出错时,就会被WorkerWatcher监听到,进而终止Executor的过程。

Driver如何晓得Executor存活

Executor收到Drvier注册胜利的音讯后,就开始创立Executor对象,这个对象实例化后,就会开始对Driver的心跳申请,因为可能会多个Executor启动,所以为了防止同一时间申请过多,这里的延时工夫会加一个随机值。

心跳接收器接管到心跳申请后,先看看这个Executor是否曾经注册了,如果没有,让Executor从新注册,如果注册过了,则更新工夫。

心跳接收器有一个定时工作,会扫描每个Executor最初上报的工夫,如果Executor曾经超过肯定工夫没有发心跳了,就会把这个Executor的信息从内存中移除,并且提交“杀死”Executor的工作。

这个工作最初会发送到ClientEndpoint,ClientEndpoint再转发给Master。