ZAB选举算法
01. 什么是Zab协议?
Zab协议的全称是 Zookeeper Atomic Broadcast (Zookeeper原子广播)。
Zookeeper 是通过Zab协议来保证分布式事务的最终一致性。
-
Zab协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议 ,是Zookeeper保证数据一致性的核心算法。Zab借鉴了Paxos算法,但又不像Paxos那样,是一种通用的分布式一致性算法。它是特别为Zookeeper设计的支持崩溃恢复的原子广播协议。
-
在Zookeeper中主要依赖Zab协议来实现数据一致性,基于该协议,zk实现了一种主备模型(即Leader和Follower模型)的系统架构来保证集群中各个副本之间数据的一致性。
这里的主备系统架构模型,就是指只有一台客户端(Leader)负责处理外部的写事务请求,然后Leader客户端将数据同步到其他Follower节点。
Zookeeper客户端会随机的链接到Zookeeper集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向Leader提交事务,Leader接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。
Zab协议的特性:
1)Zab协议需要确保那些已经在 Leader 服务器上提交(Commit)的事务最终被所有的服务器提交。
2)Zab协议需要确保丢弃那些只在 Leader 上被提出而没有被提交的事务。
01. ZAB协议三阶段
- 发现(Discovery):选举Leader过程。
- 同步(Synchronization):选举出新的Leader后,Follwer或者Observer从Leader同步最新的数据。
- 广播:同步完成后,就可以接收客户端新的事务请求,并进行消息广播,实现数据在集群节点的副本存储。
02. 服务器状态
- LOOKING
寻找Leader状态,当服务器处于此状态时,表示当前没有Leader,需要进入选举流程 - FOLLOWING
跟随者状态,表明当前服务器角色是Follower - OBSERVING
观察者状态,表明当前服务器角色是Observer - LEADING
领导者状态,表明当前服务器角色是Leader
03. 集群链接建立过程
是基于TCP协议建立链接的,为了避免重复创建两个节点之间的TCP连接,zk按照myid数值方向来建立连接,即小数的节点发起大的节点连接。
例如,3台机器id分别为1/2/3,则发起链接的过程为:1发起对2的链接,1发起对3的链接,2发起对3的链接
04. Leader选举的触发时机
- 集群启动
- 寻找Leader状态
- 当服务器处于此状态时,表示当前没有Leader,需要进入选举流程
- 奔溃恢复
- Leader宕机
- 网络原因导致过半节点与Leader心跳中断
05. 影响成为Leader的因素
- 数据新旧程度
- 只有拥有最新数据的节点才有机会成为Leader
- 通过事物id(zxid)的大小表示数据的新旧,越大代表数据越新
- myid
- 集群启动前,会在data目录下配置myid文件,内容代表ZK服务节点的编号
- 当ZK服务器节点数据都保持最新数据时,myid中数字越大的就会被选举为Leader
- 当集群中已有Leader时,新加入的节点不会影响原来的集群
- 投票数量
- 只有获得过半投票才能选举为Leader
- 多半即:n/2 + 1,其中n为集群节点数
优先用数据的新旧,其次用myid的大小
- zxid的构成
- 主进程周期
也叫epoch,每进行一次选举,主进程的周期加一,
zxid总共由64位组成,其高32位代表主进程周期,
比较数据新旧的时候,先比较epoch的大小 - 事务单调递增的计数器
- zxid低32位表示,选举完成后,从0开始
06. Leader选举的过程
初次选举过程
- 三个ZK节点,都没有数据,对应的myid分别为1,2,3
-第一步,启动myid为1的节点,此时zxid为0,此时没法选举出主节点
-第二步,启动myid为2的节点,此时zxid为0,此时2节点选举为主节点
-第三步,启动myid为3的节点,因为已经有主节点,节点3加入,节点2仍然是主节点
宕机选举
- 场景说明
- 3台机器,此时server2为主,并且sever2宕机
- 选举流程
- 变更状态
当leader宕机后,其他节点的状态变味LOOKING - 每个server发出一个投自己的票的投票
生成投票信息(myid, zxid)
假定:server1为(1,123),server3为(2,122)
server1发给server3,server3发给server1 - 接收投票
- 投票处理
- server3收到server1,因为server1的123比122大,所以server3修改自己的投票为(1,123)然后发给server1
- server1收到server3的投票,因为123大于122,因此不改变自己的投票
- 统计投票
- server3统计:自己收到投票(包括自己投的)中,(1,123)是2票
- server1统计:自己收到投票(包括自己投的)中,(1,123)是2票
- 修改服务器状态
- server3:选出的leader是1,而自己是3,因此自己进入Followering状态,即Follower角色
- server1,选出的leader是1,自己就是1,因此自己进入LEADING状态,即自己是Leader角色
宕机选举完毕后,现leader和follower有可能会有一定的差异,需要进行同步
07. 广播
广播流程
- 集群选举完成,并且完成数据同步后,即可开始对外服务,接收读写请求
- 当Leader接收到客户端新的事务请求后,会生成对应的事务proposal,并根据zxid的顺序所有的follower发送提案,即proposal
- 当follower收到leader的事务proposal时,根据接收的先后顺序处理这些proposal,即如果先后收到1,2,3条,则如果处理完了3条,则代表1,2两条一定已经处理成功
- 当Leader收到follower针对某个事务proposal过半的ack后,则发起事务提交,重新发起一个commit的proposal
- follower收到commit的proposal后,记录事务提交,并把数据更新到内存数据库
- 补充说明
由于只有过半的机器给出反馈,则可能存在某时刻某些节点数据不是最新的
业务上如果需要读取到的数据时最新的,则可以在读取之前,调用sync方法进行数据同步