Zookeeper ZAB协议-Leader&Followe 对象创建和启动源码解析
这篇博客主要是解析了Leader,Follower 对象的创建,相对来说比较简单,主要是了解一下在实例化的时候创建了哪些对象,这些对象会在数据传输的过程中发挥比较打的作用,如果有了解过的,可以直接跳过
因为Zookeeper 启动的一些加载在前一篇文章zookeeper选举流程源码解析 中已经进行解析过了,这里直接从QuorumPeer.run
方法开始,在通过快速选举机制选出来Leader,Follower 后会进行相应的对象创建
我们从Leader 开始解析,客户端所有的写操作都是经过leader处理,然后将数据同步给Follower, Observer
QuorumPeer.run.Leading
在确认当前节点为leading节点的时候,会通过
makeLeader
创建leader 对象见QuorumPeer.makeLeader
leader.lead
启动见Leader.lead
QuorumPeer.makeLeader
Leader.lead
因为这里只跟主流程,省略了一些代码,防止代码太过繁琐杂乱
1: 会创建一个线程专门处理leader 节点和follower节点socket连接,见LearnerCnxAcceptor
2; 启动Leader Zookeeper
, 见 startZkServer
LearnerCnxAcceptor
LeaderHandler
是每一个连接都有一个新建了一个线程处理,和选举的机制相似,在LeaderHandler
的run 方法中执行具体的逻辑,见LeaderHandler.run
LeaderHandler#run
这里只截取了部分代码,可以看到会根据数据的不同类型走不同的逻辑,比如说ping, ack
等,具体的代码后续再分析
Leader#startZkServer
zk.startup
-> LeaderZooKeeperServer.startup
-> ZooKeeperServer.startup
, 这里最终会调用到 ZooKeeperServer.startup
,见ZooKeeperServer.startup
ZooKeeperServer.startup
ZooKeeperServer.startup
为了让processor 有更直观的影响,这里先展示一下processor 的链式调用图如下
并且因为zk对象是LeaderZookeeperServer
,所以setupReuqestProcessors
方法会调用LeaderZookeeperServer
的setupReuqestProcessors
方法,见LeaderZookeeperServer#setupReuqestProcessors
LeaderZookeeperServer#setupReuqestProcessors
LeaderZookeeperServer#setupReuqestProcessors
总结一下:
1: 在方法中主要是创建了一系列的Processor 对象
2:commitProcessor
, SyncRequestProcessor
, PreRequestProcessor
这3个对象都是继承与Thread, 直接在这个位置启动了线程,这里稍微在解释一下,因为这3个线程的run 方法中都有从阻塞队列中获取数据,因为这时候还没有和客户端进行交互,这个时候都是处于阻塞的状态,这里的run 方法就不在这里解析了,在和zk 客户端交互的时候再进行解析
好了,LeaderZookeeperServer的启动流程就暂时先介绍到这里,下面说一下Follower 的启动流程
QuorumPeer.run.Following
执行FillowLeader
方法见Follower#followLeader
Follower#followLeader
稍微总结一下:
1: 首先是根据投票信息获取leader 节点的对象
2: 和leader 节点建立连接,如果阅读过Leader 节点的创建,应该了解到,在创建leaderServer
对象的时候,会创建一个同步数据的socket ss, 然后阻塞在accept 方法上,这里follower 就是和这个socket 对象进行连接, 见 connectToLeader
3: 与leader 进行数据同步,比如说这个节点是新加入的,不存在任何数据,那么需要将之前的数据进行同步,或者某个节点网络分区了,后续重新加入进来,为了保持数据一致性,也需要数据同步,同时也是在这里调用startup 方法启动followerServer
的, 见syncWithLeader
4: 死循环接收leader同步数据,就是真正实现处理ZAB 协议的代码
Learner#connectToLeader
Learner#syncWithLeader
这个方法主要是实现了Follower 在启动的时候 和 Leader 数据同步,主要是同步Leader 主节点点中已经执行过,但是Follower 中还不存在的数据, ZK 提供了4种同步方式
DIFF
差异化同步,一般都是Leader 节点事务 > Follower 节点TRUNC
回滚操作, Follower 节点日志回滚到和Leader 节点一直的情况TRUNC+DIFF
回滚+同步 一般是Follower 服务器上存在一条事务日志,但是在Leader 上不存在,这种情况出现较少,只有在前leader 节点出现宕机了,然后选举新节点的后才可能发生SNAP
全量更新,就是集群新加入一个节点,会优先全量同步数据
然后跟leader 节点一样,调用了startup 设置了一些processor,见,startup
ZooKeeperServer.startup
这里的和Leader 不一样,这里的Server 是FollowerKeeperServer
FollowerKeeperServer#setupRequestProcessors
这里构建的方式也是一样,构建了Processor 链,如下图,同时CommitProcessor
, SyncProcessor
都是线程子类,在启动的时候因为队列为空,被阻塞住,不过commitProcess
是调用了wait 方法, 而 SyncProcessor
是因为阻塞队列的原因被阻塞住
好了,在这里Follower 启动分析基本完成,有了这些基本储备,我将在下一篇博客根据流程分析一下数据从客户端到服务端操作完成后返回数据的整个流程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南