zab协议全称为zookeeper atomic boradcast(原子广播协议)
zab协议是借鉴Paxos的思想来实现的一种保证分布式架构中数据一致性的算法
zab的协议包含两种 一种是原子广播协议 一种是崩溃恢复协议
原子:要么成功,要么失败,不存在中间状态(队列+2阶段提交)
广播:在分布式多节点中,不是所有节点都会接收到广播,但会过半通过。
所谓的崩溃恢复 就是在Leader节点崩溃下线后,从有效的Follower节点中推选出一个新的Leader,从而让整个集群继续对外提供服务,在选择的阶段可能会导致各个节点存在数据不一致的问题。
在选举的时候会参考两个重要的参数:
谁的票数最多谁就会变为leader 前提是票数是超过节点机器的半数
zxid 是一个用于标识事务的唯一标识符。每个事务在ZooKeeper中都会被分配一个唯一的ZXID。
ZXID由两部分组成:高位部分表示事务的Epoch(选举轮次),低位部分表示事务的序列号。Epoch是在领导者选举过程中使用的概念,用于区分不同的选举周期。序列号用于在选举周期内对事务进行排序
当一个节点成为ZooKeeper集群的领导者时,它会生成具有较高Epoch值的ZXID。在该选举周期内,领导者生成的所有事务都具有较高的Epoch值。当选举周期结束并发生新的选举时,新领导者会增加Epoch值,以区分新的选举周期。
ZXID在ZooKeeper中的使用非常重要。它用于确定事务的顺序和一致性。比较两个ZXID可以确定哪个事务先发生,从而保证了数据的正确顺序和一致性。
总之,ZXID是ZooKeeper中用于标识事务的唯一标识符,由Epoch和序列号组成,用于维护事务的顺序和一致性。
相比于完整的二阶段提交,Zab 协议最大的区别就是不能终止事务,follower 要么回 ACK 给 leader,要么抛弃 leader,在某一时刻,leader 的状态与 follower 的状态很可能不一致,因此它不能处理 leader 挂掉的情况,所以 Zab 协议引入了恢复模式来处理这一问题。
从另一角度看,正因为 Zab 的广播过程不需要终止事务,也就是说不需要所有 follower 都返回 ACK 才能进行 COMMIT,而是只需要合法数量(2n+1 台服务器中的 n+1 台) 的follower,也提升了整体的性能。
zookeeper崩溃恢复有两个场景
1.每个Server会发出一个投票,第一次都是投自己。投票信息:(myid,ZXID)
2.收集来自各个服务器的投票
3.处理投票并重新投票,处理逻辑:优先比较ZXID,然后比较myid
4.统计投票,只要超过半数的机器接收到同样的投票信息,就可以确定leader
5.改变服务器状态,进入正常的消息广播流程。
当 leader 收到合法数量 follower 的 ACKs 后,就向各个 follower 广播 COMMIT 命令,同时也会在本地执行 COMMIT 并向连接的客户端返回「成功」。但是如果在各个 follower 在收到 COMMIT 命令前 leader 就挂了,导致剩下的服务器并没有执行都这条消息。
答案:
我的理解是这样的。 当前leader同步的该条数据没有被follower提交就挂了。 然后follower中就选举出来的一个新的leader 此时是不是在对外提供服务中,刚才写入的数据是无法获取到的?因为此时该leader节点的那条数据并没有被提交?。。 如果此后原leader节点启动了,是如何把刚才的那条数据的提交操作与其它节点处理的呢?
所以zookeeper zab协议还是一个最终实现一致性的实现是吧。 我可以保证各个节点数据完全一致,但是在特殊情况下(就比如我刚才描述的情况下) 是会有延迟的(我感觉是这样的 还是一个最终一致性的实现)