ZAB(Zookeeper Atomic Broadcast)协议,即原子广播协议用于zookeeper实现分布式事务的一致性。
ZAB协议将zookeeper集群状态分为两个类型:崩溃恢复、消息广播。
- 消息广播
消息广播即正常接收处理客户端请求,相当于一个简化的二阶段提交协议。
首先leader为每个事务生成一个proposal,将其发给所有的follower,follower收到proposal后先写日志,然后返回ack。leader在收到过半ack就提交事务,并向所有follower发送commit消息,follower收到消息后执行事务提交。
为了保证事务的顺序性,同时避免同步阻塞,leader为每个follower维护了一个消息队列。leader向消息队列顺序写消息,follower从消息队列获取消息并顺序性的执行。
消息广播解决了二阶段协议的阻塞问题,但仍存在单点问题和宕机时的一致性问题,这个就要崩溃恢复来解决。 - 崩溃恢复
当leader不可用或者与超过半数follower断开链接后,集群将进入崩溃恢复模式。
该模式下ZAB要确保两点:
1.在leader上提交的事务必须在所有服务器要提交
2.必须丢弃只在leader上提出的事务
实现以上两点就能保证崩溃时的数据一致性,怎么实现的呢?
实际上ZAB为集群中每个事务都分配了一个64位的唯一事务zxid,该zxid高32位是leader的epoch严格递增计数,低32位是该leader epoch周期每个事务严格递增计数。在leader选举时,优先选举zxid最大的作为leader就能保证leader包含集群中所有已提交事务(两次过半集合必定存在交集)。数据同步时,将新选举的leader事务同步给其他follower就可以完成数据一致性。
那么旧的leader恢复后重新加入集群,其未完成提交的事务会影响嘛?
不会,因为新选举的leader epoch更大。宕机的旧leader重新加入时,校验其epoch不统一,其为提交的事务也将进行丢弃。