首先来到这里的同学应该都学了spark相关知识,对于master跟work的启动注册源码感兴趣的可以往下看看
master的启动注册机制
首先看一下start-master.sh脚本
这是最后一行代码,可见他去调用了spark-daemen。Sh,传了一个参数class
然后进入spark-daemon.sh脚本里看看
发现里面有一个模式匹配,匹配我们传过来的值,如果参数是一个类,就调用第一个class的执行结果,又去掉spark-class来执行这一连串的启动,
到这脚本已经看完了,接下来该到上面那个class对应的master类里看看了
Master源码分析
我们先进到master的类中,然后找到object伴生对象
然后进入到主函数 main
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181229235609526.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyNzM2OTk5,size_16,color_FFFFFF,t_70
然后封装了一些参数,并调用startRpcEnvandEndpoint方法来创建rpcEnv启动rpc通信
在1.6之前呢。都是使用actor来创建的,1.6跟2.2是一样的机制都是startRPC…分别来创建,
然后进到这个startRpcEnvandEndpoint方法里面
跟踪这个startRpcEnvandEndpoint启动方法跟踪这个start启动方法
可以看到通过这个rpcEnv创建了一个对象create-》继续跟踪这个方法可以看到通过这个rpcEnv创建了一个对象create-》继续跟踪这个方法
查看这个create查看这个create
到这里,创建RpcEnv的工作就完成了,注意真正创建RPCEnv的是调用了一个工厂类NettyRpcEnvFactory创建的
到此,创建rpcEnv对象完成,通过这个rpcEnv对象创建masterEndpoint之前是AkkaUtils创建返回。后面版本都换了
下一步:细心的同学在上面调用startRpcEnvandEndpoint这个方法的时候,如果成功了创建rpcenv对象之后会执行new Master(),
Master创建成功之后,开始执行检查work节点的操作。首先会调用onstart方法
60s开始检查一次work
检查源码 timeOutDeadWorkers 如果超时了,那么就从works里面把当前这个work当作死亡处理,
onStart()方法除了启动了webUI, restServer, metrics等诸多服务外,还分别启动了对Worker TimeOut的Check和HA,Worker TimeOut Check相对简单没什么好说的,主要看一下HA部分,这部分代码共有三个分支,这里主要分析基于Zookeeper的HA
val serializer = new JavaSerializer(conf)
val (persistenceEngine_, leaderElectionAgent_) = RECOVERY_MODE match {
case "ZOOKEEPER" =>
logInfo("Persisting recovery state to ZooKeeper")
val zkFactory =
new ZooKeeperRecoveryModeFactory(conf, serializer)
(zkFactory.createPersistenceEngine(), zkFactory.createLeaderElectionAgent(this))
case "FILESYSTEM" =>
val fsFactory =
new FileSystemRecoveryModeFactory(conf, serializer)
(fsFactory.createPersistenceEngine(), fsFactory.createLeaderElectionAgent(this))
case "CUSTOM" =>
val clazz = Utils.classForName(conf.get("spark.deploy.recoveryMode.factory"))
val factory = clazz.getConstructor(classOf[SparkConf], classOf[Serializer])
.newInstance(conf, serializer)
.asInstanceOf[StandaloneRecoveryModeFactory]
(factory.createPersistenceEngine(), factory.createLeaderElectionAgent(this))
case _ =>
(new BlackHolePersistenceEngine(), new MonarchyLeaderAgent(this))
}
基于ZK的模式下Master将App,Worker,Driver序列化成ZK的节点,这样如果Active的Master宕机,Standby的Master可以通过从ZK节点上读取数据来保证状态信息不丢失
在检查work节点超时的时候,有一个超时算法
检查完超时的work之后
上面全部都是初始化操作,下面才真正开始进入任务状态,
等待接收信息
检查完超时的work之后
上面全部都是初始化操作,下面才真正开始进入任务状态,
等待接收信息
在等待接收的内部有一个等待注册的方法
reseive才会接收到消息,调用work想master注册方法,然后加入到自己的集群当中。然后继续等待work的注册,至此master的启动就到此结束了,
下面继续为大家讲解work源码分析
首先呢,work启动也是通过脚本的方式,start-slaves,里面有一个启动类,这里补贴出来了,跟master一样,org.xxxx.然后下面调用spark-daemon.sh脚本,创建之后再调用spark-class脚本开始执行,然后开始开始进入main函数
步骤一:
在main函数中,封装了一些参数,跟master一样的,调用了startRpcEnvAndEndpoint创建rpcEnv对象,也是通过rpcEnv对象进行调用的
步骤二:
在startRpcEnvAndEndpoint()中创建了rpcEnv和endpoint,跟master执行逻辑一样,这里就不再叙述了,当创建rpc对象返回之后,执行new work(),然后执行work的onstart方法
这里有个想master发送注册信息的方法,里面有一些方法信息的机制
首先、获取了所有的master的URL,向所有的master地址注册一遍,
问题:这里为啥要获取多个,不是只有一个吗?
解决:因为在开发过程中,都是高可用的,一个active的master跟好多等待状态的master共同实现的,也就是HA高可用
第二步:大家注意到上面有一个属性 registered=false,还有一个连接尝试数量=0
当他获取到连接的时候,开始请求注册操作,如果注册失败会继续注册,超过15次就不再注册了,如果连接成功,就把状态registered改为true
连接成功后,会调用一个sendRegisterMessageToMaster的操作,开始注册work,注册成功之后开始执行任务
小编下次会将仔细研读 submit stage划分的源代码 ,请多多关注,欢迎转载