zookeeper原理之Leader选举完成之后的处理逻辑
通过 lookForLeader 方法选举完成以后,会设置当前节点的 PeerState,要么为 Leading、要么就是 FOLLOWING、或者 OBSERVING到这里,只是表示当前的 leader 选出来了,但是 QuorumPeer.run 方法里面还没执行完,我们再回过头看看后续的处理过程。
QuorumPeer.run
分别来看看 case 为 FOLLOWING 和 LEADING,会做什么事情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | @Override public void run() { setName( "QuorumPeer" + "[myid=" + getId() + "]" + cnxnFactory.getLocalAddress()); while (running) { switch (getPeerState()) { case LOOKING: case OBSERVING: case FOLLOWING: try { LOG.info( "FOLLOWING" ); setFollower(makeFollower(logFactory)); follower.followLeader(); } catch (Exception e) { LOG.warn( "Unexpected exception" ,e); } finally { follower.shutdown(); setFollower( null ); setPeerState(ServerState.LOOKING); } break ; case LEADING: LOG.info( "LEADING" ); try { setLeader(makeLeader(logFactory)); leader.lead(); setLeader( null ); } catch (Exception e) { LOG.warn( "Unexpected exception" ,e); } finally { if (leader != null ) { leader.shutdown( "Forcing shutdown" ); setLeader( null ); } setPeerState(ServerState.LOOKING); } break ; } //省略部分代码 } |
makeFollower
初始化一个 Follower 对象,构建一个 FollowerZookeeperServer,表示 follower 节点的请求处理服务。
1 2 3 | protected Follower makeFollower(FileTxnSnapLog logFactory) throws IOException { return new Follower( this , new FollowerZooKeeperServer(logFactory, this , new ZooKeeperServer.BasicDataTreeBuilder(), this .zkDb)); } |
follower.followLeader();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | protected Follower makeFollower(FileTxnSnapLog logFactory) throws IOException { return new Follower( this , new FollowerZooKeeperServer(logFactory, this , new ZooKeeperServer.BasicDataTreeBuilder(), this .zkDb)); } follower.followLeader(); void followLeader() throws InterruptedException { //省略部分代码 try { //根据 sid 找到对应 leader,拿到 lead 连接信息 QuorumServer leaderServer = findLeader(); try { //连接到 Leader connectToLeader(leaderServer.addr, leaderServer.hostname); //将 Follower 的 zxid 及 myid 等信息封装好发送到 Leader,同步 epoch。 也就是意味着接下来 follower 节点只同步新 epoch 的数据信息 long newEpochZxid = registerWithLeader(Leader.FOLLOWERINFO); //如果 leader 的 epoch 比当前 follow 节点的 poch 还小,抛异常 long newEpoch = ZxidUtils.getEpochFromZxid(newEpochZxid); if (newEpoch < self.getAcceptedEpoch()) { LOG.error( "Proposed leader epoch " + ZxidUtils.zxidToString(newEpochZxid) + " is less than our accepted epoch " + ZxidUtils.zxidToString(self.getAcceptedEpoch())); throw new IOException( "Error: Epoch of leader is lower" ); } //和 leader 进行数据同步 syncWithLeader(newEpochZxid); QuorumPacket qp = new QuorumPacket(); while ( this .isRunning()) { //接受 Leader 消息,执行并反馈给 leader,线程在此自旋 readPacket(qp); //从 leader 读取数据包 processPacket(qp); //处理 packet } } catch (Exception e) { LOG.warn( "Exception when following the leader" , e); try { sock.close(); } catch (IOException e1) { e1.printStackTrace(); } // clear pending revalidations pendingRevalidations.clear(); } } finally { zk.unregisterJMX((Learner) this ); } } |
makeLeader
初始化一个 Leader 对象,构建一个 LeaderZookeeperServer,用于表示leader 节点的请求处理服务。
1 2 3 | protected Leader makeLeader(FileTxnSnapLog logFactory) throws IOException { return new Leader( this , new LeaderZooKeeperServer(logFactory, this , new ZooKeeperServer.BasicDataTreeBuilder(), this .zkDb)); } |
leader.lead();
在 Leader 端, 则通过 lead()来处理与 Follower 的交互leader 和 follower 的处理逻辑这里就不再展开来分析,朋友们可以自己去分析并且画出他们的交互图。
分类:
zookeeper
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具