zookeeper源码解析流程图
2022-04-13 14:48:31 0 举报
zookeeper源码解析流程图,轻松学习zk源码
作者其他创作
大纲/内容
makeLEStrategy().lookForLeader()
readonlymode.enabled
receiveConnection(client);
NO
NO,当前节点胜
处理连接信息
sid:sendqueue
sid:senderworker
NO使用选举策略选举leader
建立新socket连接
recvqueue.offer(n)
sid= din.readLong()
循环将选票信息发送出去
quorum属性填充
选票信息校验
n.electionEpoch < logicalclock.get() 说明发票的机器刚刚加入集群,这种选票一般会废弃掉
Messenger.start()
sid:recevierworker
this.wrThread.start()
YES
sid等于self.id 警告:配置可能错误
发送消息
sendqueue
判断当前server状态是否是LOOKING状态
ServerCnxnFactory.createFactory()
创建选举的server socket(选举用的是普通的socket通信BIO)
self.getPeerState() == ServerState.LOOKING
选票PK,选举周期落后,认为是中途加入集群不,不能会直接选举自己。需要用接收到的选票和自己PK
解析配置文件,加载到内存中
n.electionEpoch logicalclock.get()
判断
判断选举地址是否为null
n.electionEpoch = logicalclock.get()
process(m)
根据配置文件:zookeeper.serverCnxnFactory中配置创建通讯方式
判断其他节点是否发送选票
sId < self.id
原子操作:增加选举年龄、初始化选票(首次选择自己)
startServerCnxnFactory()
sendqueue.offer(notmsg)
放入recvqueue
执行发送线程
n.electionEpoch == logicalclock.get()
send
wokerReceiver.run()
electionAddr == null
启动核心方法
配置集群节点的通信方式
workerReceier
判断选票状态(发送发状态)
recvqueue
启动初始化zk方法
接收选票放入recvQueue
adminServer.start()
QuorumCnxManager.Listener listener = qcm.listener
notification == null
self.setPeerState((proposedLeader == self.getId()) ? ServerState.LEADING: learningState())
//将当前的节点的选举周期替换为选票的选举周期logicalclock.set(n.electionEpoch)//清空该节点的接收的选票箱记录recvset.clear()
将接收到的选票放入recvQueue中异步处理
quorumPeer.start()
如果发送选票方还没有leader就将本机认为的leader发送给他(中途新加机器的情况)
根据配置文件:zookeeper.serverCnxnFactory中配置创建通讯方式。如果没有配置默认使用NIO方式。PS:ZK官方推荐使用NETTY进行节点之间的通讯。
workerSender.run()
(ackstate == QuorumPeer.ServerState.LOOKING) && (n.electionEpoch < logicalclock.get())
manager.connectAll()
不是looking状态说明现在已经有leader了,不需要再选举
启动监听
sw.finish()
validVoter(n.sid) && validVoter(n.leader)
YES,接收到的选票胜
集群Leader选举流程
开启清除快照文件任务
根据前面的配置知道这里是FLE策略选举
QuorumPeerMain
添加到sendqueue中
执行接收线程
Vote current = self.getCurrentVote()
添加到sendqueue
recvQueue
config.parse(args[0])
this.wsThread.start()
workerSender
启动选举
SendWorker sw = senderWorkerMap.get(sid)
startLeaderElection()
sendNotifications()
从接收队列里面取选票
super.start()
加粗条件表示双方共用,未加粗条件表示左边独用
listener.start()
n == null
socket读取选票信息
NETTY
半数选举leader逻辑
是否只读
循环从recvqueue中获取其他节点的选票
recvWorker.run()
LOOKING
NIOServerCnxnFactory
fastLeaderElection.lookForLeader()
将PK后接收到的选票放入选recvqueue中
queueSendMap.size() == 0
注意:socket连接是双向的,只要连接一次双方server都能够进行通信,为了减少不必要的连接,都尽量只连接一次。zookeeper作者有一个规则:那就是在zk中的socket连击只能是由myId大的zk去连接myId小的zk。因此如果zk发现连接自己的socket的myid比自己小就会删除senderWorkerMap中对应的sw同时删除此次socket连接,会重新通过myid较大的zk去连接myid小的zk。
创建监听器
发送选票
从发送队列里面取选票
connectOne(sid)
sid self.id
获取选票
开始选举
zk sever1
received
zk sever2
purgeMgr.start()
closeSocket(socket)
loadDataBase()
启动快速选举算法
NettyServerCnxnFactory
选举核心逻辑
如果self.idsid发送选票时发送自己
senderWoker.run()
比较接收到的选票的选举周期和当前节点的选举周期
启动workerSender线程
建立socket连接
sid == self.id
Main.initializeAndRun()
runFromConfig(config)
判读是否还需要做leader重新选举
socket
关于zk底层中的queue的关系说明:
quorum执行
NIO/不配置
leaveInstance(endVote);return endVote
oldq == null
创建leader算法
InitQuorum
接收其他server socket的连接
leader > cur
connectOne(sid)
是否还能收到选票信息
启动wokerRecver线程
createElectionAlgorithm(electionType)
sw == null
收藏
0 条评论
回复 删除
下一页