聊一聊ZooKeeper的次序一致性

ZooKeeper作为分布式运用体系和谐服务,在分布式体系中的运用十分广泛,在某些业务场景下乃至能够作为注册中心、分布式锁来运用。ZooKeeper之所以能有如此广泛的运用,与它杰出的数据一致性保障机制是分不开的。咱们都知道ZooKeeper专门规划了Zab(Zookeeper Atomic Broadcast)协议作为其数据一致性协议。
运用Zab协议的数据写入由Leader结点和谐,运用两阶段提交的方法,到达数据的终究一致性。为什么是终究一致性呢?咱们先了解下两阶段的进程,如图一所示:
聊一聊ZooKeeper的次序一致性
图一

数据写入进程如下:

第一阶段:每次的数据写入事情作为提案播送给一切Follower结点;能够写入的结点回来承认信息ACK;第二阶段:Leader收到一半以上的ACK信息后承认写入能够收效,向一切结点播送COMMIT将提案收效。

依据写入进程的两阶段的描绘,咱们知道ZooKeeper确保的是终究一致性,即Leader向客户端回来写入成功后,可能有部分Follower还没有写入最新的数据,所以是终究一致性。

咱们都知道ZooKeeper确保的终究一致性也叫次序一致性,即每个结点的数据都是严厉按业务的建议次序收效的。

ZooKeeper是怎么确保业务次序的呢?

这儿需求了解下它的业务ID(ZXID),之前的文章介绍过ZooKeeper的在推举时经过比较各结点的ZXID和机器ID选出新的注结点的。ZXID由Leader节点生成,有新写入事情时,Leader生成新ZXID并随提案一同播送,每个结点本地都保存了当时最近一次业务的ZXID,ZXID是递加的,所以谁的ZXID越大,就表明谁的数据是最新的。

ZXID的生成规矩如下图所示:

聊一聊ZooKeeper的次序一致性
图二

ZXID有两部分组成:

任期:完结本次推举后,直到下次推举前,由同一Leader担任和谐写入;业务计数器:单调递加,每收效一次写入,计数器加一。

能够看到,ZXID的低32位是计数器,所以同一任期内,ZXID是接连的,每个结点又都保存着本身最新收效的ZXID,经过比照新提案的ZXID与本身最新ZXID是否相差“1”,来确保业务严厉依照次序收效的。

咱们都知道ZooKeeper集群的写入是由Leader结点和谐的,实在场景下写入会有必定的并发量,那Zab协议的两阶段提交是怎么确保业务严厉按次序收效的呢?在本章介绍两阶段提交的部分描绘了Leader在收到对折以上ACK后会将提案收效并播送给一切Follower结点。

Leader为了确保提案按ZXID次序收效,运用了一个ConcurrentHashMap,记载一切未提交的提案,命名为outstandingProposals,key为ZXID,Value为提案的信息。对outstandingProposals的拜访逻辑如下:

1、每建议一个提案,会将提案的ZXID和内容放到outstandingProposals中,作为待提交的提案;

2、收到Follower的ACK信息后,依据ACK中的ZXID从outstandingProposals中找到对应的提案,对ACK计数;

3、履行tryToCommit测验将提案提交,判别流程如下:

3.1:判别当时ZXID之前是否还有未提交提案,假如有,当时提案暂时不能提交;

3.2:判别提案是否收到对折以上ACK,假如到达对折则能够提交;

3.3:假如能够提交,将当时ZXID从outstandingProposals中铲除并向Followers播送提交当时提案;
Leader是怎么判别当时ZXID之前是否还有未提交提案的呢?因为条件是确保次序提交的,所以Leader只需判别outstandingProposals里,当时ZXID的前一个ZXID是否存在,代码如下:

聊一聊ZooKeeper的次序一致性
图三
所以ZooKeeper是经过两阶段提交确保数据的终究一致性,而且经过严厉的依照ZXID的次序收效提案确保其次序一致性的。