Zookeeper 规定所有有效的投票都必须在同一个 轮次 中 , 每个服务器在开始新一轮投票时 , 都会对自己维护的 logicalClock 进行自增操作 。
每个服务器在广播自己的选票前 , 会将自己的投票箱(recvset)清空 。该投票箱记录了所收到的选票 。
例如:Server_2 投票给 Server_3 , Server_3 投票给 Server_1 , 则Server_1的投票箱为(2,3)、(3,1)、(1,1) 。(每个服务器都会默认给自己投票)
前一个数字表示投票者 , 后一个数字表示被选举者 。票箱中只会记录每一个投票者的最后一次投票记录 , 如果投票者更新自己的选票 , 则其他服务器收到该新选票后会在自己的票箱中更新该服务器的选票 。
这一阶段的目的就是为了选出一个准 Leader , 然后进入下一个阶段 。
协议并没有规定详细的选举算法 , 后面会提到实现中使用的 Fast Leader Election 。
文章插图
- 发现阶段(Descovery)
一个 Follower 只会连接一个 Leader , 如果一个 Follower 节点认为另一个 Follower 节点 , 则会在尝试连接时被拒绝 。被拒绝之后 , 该节点就会进入 Leader Election阶段 。
这个阶段的主要目的是发现当前大多数节点接收的最新 Proposal , 并且准 Leader 生成新的 epoch , 让 Followers 接收 , 更新它们的 acceptedEpoch 。
文章插图
- 同步阶段(Synchronization)
只有当 quorum(超过半数的节点) 都同步完成 , 准 Leader 才会成为真正的 Leader 。Follower 只会接受 zxid 比自己 lastZxid 大的 Proposal 。
文章插图
- 广播阶段(Broadcast)
需要注意的是 , Zab 提交事务并不像 2PC 一样需要全部 Follower 都 Ack , 只需要得到 quorum(超过半数的节点)的Ack 就可以 。
文章插图
Zab协议实现协议的 Java 版本实现跟上面的定义略有不同 , 选举阶段使用的是 Fast Leader Election(FLE) , 它包含了步骤1的发现职责 。因为FLE会选举拥有最新提议的历史节点作为 Leader , 这样就省去了发现最新提议的步骤 。
实际的实现将发现和同步阶段合并为 Recovery Phase(恢复阶段) , 所以 , Zab 的实现实际上有三个阶段 。
Zab协议三个阶段:
- 选举(Fast Leader Election)
- 恢复(Recovery Phase)
- 广播(Broadcast Phase)
前面提到的 FLE 会选举拥有最新Proposal history (lastZxid最大)的节点作为 Leader , 这样就省去了发现最新提议的步骤 。这是基于拥有最新提议的节点也拥有最新的提交记录
成为 Leader 的条件:
- 选 epoch 最大的
- 若 epoch 相等 , 选 zxid 最大的
- 若 epoch 和 zxid 相等 , 选择 server_id 最大的(zoo.cfg中的myid)
文章插图
Recovery Phase(恢复阶段)
这一阶段 Follower 发送他们的 lastZxid 给 Leader , Leader 根据 lastZxid 决定如何同步数据 。这里的实现跟前面的 Phase 2 有所不同:Follower 收到 TRUNC 指令会终止 L.lastCommitedZxid 之后的 Proposal , 收到 DIFF 指令会接收新的 Proposal 。
推荐阅读
- 央视|央视网评App用户协议太长:就是不想让用户看明白!
- 浅谈ARP地址解析协议
- 一文领略 HTTP 的前世今生
- 淞沪会战停战协议 淞沪停战协定后上海抗战
- 音视频开发1. 基本概念及媒体协议
- zabbix5.0 配置监控agent, 并通过微信接收报警
- IP 通俗易懂网络协议
- https ssl 请求过程详解
- rtsp协议之dss服务器与vlc服务器比较
- rtsp协议之dss搭建rtsp服务器