事务编号
在ZAB,原子消息广播协议的事务编号ZXID设计中,ZXID是一个64位数字,低32位是一个单调递增的计数器,针对每一个事务请求,计数器加1.高32位则代表leader周期epoch的编号,每个当选产生一个新的的leader服务器,就会从这个leader服务器中读出本地事务日志中的最大zxid,并从中读取epoch并且加1以此作为新的epoch,并且低32位从0开始计数。
zxid类似于RDBMS中的事务ID,用于标识一次更新操作的proposalid,为了保证顺序性,zkid必须单调递增。
epoch,当前集群的年代或者周期,每个leader当皇帝,都有自己的年号,所以每次改朝换代,leader变更之后,都会在前一个年代的基础上加1,这样就算旧leader崩溃恢复后,也不会有人听它的,follower只会听从当前年代的leader。
ZAB协议有恢复模式(选举),广播模式(同步)
当服务器启动或者leader崩溃就进入恢复模式,当leader被选举出来,且大多数server与leader的状态完成同步,恢复模式就结束。状态同步保证leader和server具有相同的状态。
ZAB协议4阶段
leader选举
节点一开始处于选举状态,只要一个节点得到超半数的节点的票数,他就可以当选准leader。只有到达广播阶段准leader才能成为真正的leader,这一阶段目的是为了选举出一个准leader,
discovery阶段:
在这个阶段followers与准leader进行通信,同步followers最近收到的事务协议,这一个阶段主要是发现大多数节点接收的最新提议,并且准leader成为新leader生成epoch,让followers接受,并且更新他们的acceptorEpoch
一个follow只会连接一个leader,如果一个节点f认为另外一个follower为leader,f尝试连接时候会被拒绝,f被拒绝后会重新进入选举状态。
同步阶段(广播阶段):
到了这个阶段,Zookeeper才能对外提供事务服务,并且leader可以进行消息广播。同时如果有新节点加入,还需要对新节点进行同步。
zab提交事务不需要像2pc一样所有follower都ack,只需要得到超半数的节点的ack就可以了。
每个server首先给自己投票,然后用自己的选票和其他的server选票对比,权重大的胜出,使用权重较大的更新自身票箱。具体选举过程如下:
1、每个server启动以后询问其他server投票给谁,对于其他的server的询问,server会根据自己的状态回复自己推荐的leader的id和上一次事务处理的zxid(系统启动的时候一般都会推荐自己)
2、收到所有server的回复,计算出zxid最大的那个server,并将这个server相关信息设置成下一个要投票的server。
3、计算这个过程获得票数最多的server作为获胜者,如果获胜者的票数超过半数,则改server为leader,否则继续这个过程,直到leader被选举出来。
4、leader开始等待server的连接
5、follower连接server,并且将最大的zxid发送给leader
6、leader根据follower的zxid确定同步点,选举阶段完成。
7、选举阶段完成leader同步后通知follower已经完成uptodate状态
8、follow完成了uptodate消息就可以重新接受client连接。
目前有5台服务器,每台服务器均没有数据,它的编号为1,2,3,4,5按编号依次启动,选举过程如下
1、服务器1启动,给自己投票,其他的服务器还没有启动无法响应,服务器1的状态一直属于looking
2、服务器2启动,给自己投票,同时与之前启动服务器交换结果,由于服务器2的编号大,所以2胜出,但是没有超过半数,所以两个服务器的状态依然是looking
3、服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号,最大所以3号服务器胜出,超过半数,所以成为leader,1,2成为小弟。
4、服务器4启动给自己投票,同时与1,2,3交换信息,但是3已经成为leader服务器4只能成为小弟
5、服务器5启动同理,后面逻辑同服务器4
zookeeper工作原理
1、zookeeper的核心是原子广播,这个机制保证各个server之间的同步,实现这个机制的就是zab协议,zab协议有两种模式,它们分别是恢复模式和广播模式。
2、当服务启动或者崩溃时,zab就进入恢复模式,当领导者被选举出来,且大多数server的完成和leader状态同步后,恢复模式就结束。
3、状态同步保证了leader和follow具有相同的状态
4、一旦leader已经和多数follow完成状态同步,他就可以进行广播了,即进入广播状态。这时候当一个server加入zookeeper状态,它会在恢复模式下启动,与leader同步状态,同步结束。它也开始进行广播消息,zookeeper一直处于广播模式,知道leader崩溃或者leader失去大部分follow收到支持。
5、广播模式需要保证propsal按顺序处理,因此zk采用了递增的事务id,所有的proposal全部加上了zxid。
6、zxid 64为为epochid 32 位,低32位单调自增。
7、当一个leader崩溃或者失去大多数follow支持,就进入恢复模式,重新选举出一个leader并且恢复正常状态