(1) 初始化广播
- 前面我们说过,恢复模式具有两个阶段:Leader 选举与初始化同步(广播)。当完成 Leader
选举后,此时的 Leader 还是一个准 Leader,其要经过初始化同步后才能变为真正的 Leader。
具体过程如下:
- 为了保证 Leader 向 Learner 发送提案的有序,Leader 会为每一个 Learner 服务器准备一个队列
- Leader 将那些没有被各个 Learner 同步的事务封装为 Proposal
- Leader 将这些 Proposal 逐条发给各个 Learner,并在每一个 Proposal 后都紧跟一COMMIT 消息,表示该事务已经被提交,Learner 可以直接接收并执行
- Learner 接收来自于 Leader 的 Proposal,并将其更新到本地
- 当 Learner 更新成功后,会向准 Leader 发送 ACK 信息
- Leader 服务器在收到来自 Learner 的 ACK 后就会将该 Learner 加入到真正可用的 Follower列表或 Observer 列表。没有反馈 ACK,或反馈了但 Leader 没有收到的 Learner,Leader不会将其加入到相应列表。
(2)更新算法广播
当集群中的 Learner 完成了初始化状态同步,那么整个 zk 集群就进入到了正常工作模式
了。
如果集群中的 Learner 节点收到客户端的事务请求,那么这些 Learner 会将请求转发给
Leader 服务器。然后再执行如下的具体过程:
- Leader 接收到事务请求后,为事务赋予一个全局唯一的 64 位自增 id,即 zxid,通过zxid 的大小比较即可实现事务的有序性管理,然后将事务封装为一个 Proposal。
- Leader 根据 Follower 列表获取到所有 Follower,然后再将 Proposal 通过这些 Follower 的队列将提案发送给各个 Follower。
- 当 Follower 接收到提案后,会先将提案的 zxid 与本地记录的事务日志中的最大的 zxid进行比较。若当前提案的 zxid 大于最大 zxid,则将当前提案记录到本地事务日志中,并向 Leader 返回一个 ACK。(提问学员)
- 当 Leader 接收到过半的 ACKs 后,Leader 就会向所有 Follower 的队列发送 COMMIT消息,向所有 Observer 的队列发送 Proposal。
- 当 Follower 收到 COMMIT 消息后,就会将日志中的事务正式更新到本地。当 Observer收到 Proposal 后,会直接将事务更新到本地。
- 无论是 Follower 还是 Observer,在同步完成后都需要向 Leader 发送成功 ACK。