分布式与一致性协议之ZAB协议(二)

ZAB协议

ZAB协议是如何实现操作地顺序性的?





如果用一句话解释ZAB协议到底是什么,我觉得它是能保证操作顺序性的、基于主备模式的原子广播协议。

接下来,还是以指令X、Y为例具体演示一下,帮助你更好地理解为什么ZAB协议能实现操作的顺序性(为了演示,我们假设节点A为主节点,节点B、C为备份节点)。

首先,在ZAB协议中,写操作必须在主节点(比如节点A)上执行。如果客户端访问的节点是备份节点(比如节点B),则备份节点会将写请求转发给主节点,如图所示。

接着,当主节点接收到写请求后,它会基于写请求中的指令(也就是X、Y)来创建一个提案(Proposal),并使用一个唯一的ID来标识这个提案。这里我说的唯一ID就是事务标识符(TransactionID,也就是zxid),如图所示

从图中可以看到,指令X、Y对应的事务标识符分别为<1,1>和<1,2>。这两个标识符是什么含义呢?

你可以这么理解,事务标识符是64位的long型变量,由任期编号epoch和计数器counter两部分组成(为了形象和方便理解,我把epoch翻译城任期编号),格式为<epoch,counter>,其中,高32位位任期编号,低32位为计数器。

1.任期编号就是创建提案时领导者的任期编号,当新领导者当选时,任期编号递增,计数器被设置为零。比如,前领导者的任期编号为1,那么新领导者对应的任期编号将为2

2.计数器就是具体标识提案的整数,每次领导者创建新的提案时,计数器将递增。比如,前一个提案对应的计数器值为1,那么新的提案对应的计数器值将为2

为什么要设计这么复杂呢?因为事务标识符必须按照顺序、唯一标识一个提案,也就是说,事务标识符必须是唯一的、递增的。

在创建完提案之后,主节点会基于TCP协议并按照顺序将提案广播到其他节点,如图所示,这样就能保证先发送的消息先被收到,进而保证消息接收的顺序性。如图所示,指令X一定在指令Y之前到达节点B、C.

然后,当主节点接收到指定提案的大多数确认响应后,该提案将处于提交状态(Commited),此时主节点会通知备份节点提交该提案,如图所示。

主节点提交提案是有顺序性的。它会根据事务标识大小顺序提交提案,如果前一个提案未提交,此时主节点是不会提交后一个提案的。也就是说,指令X一定会在指令Y之前提交。

最后,主节点返回执行成功的响应给节点B,由节点B再转发给客户端,这样我们就实现了操作的顺序性,保证了指令X一定在指令Y之前执行。

最后想补充的是,当执行完写操作后,接下来你可能需要执行读操作。为了提升读并发能力,ZooKeeper提供的是最终一致性,也就是说,读操作可以在任何节点上执行,如图所示,客户端会读到旧数据。如果客户端必须要读到最新数据,怎么办呢?ZooKeeper提供了一个解决办法,那就是sync命令。我们可以在执行读操作前执行sync命令,从而使客户端可以读到最新数据,如代码所示

c 复制代码
[zk: localhost:2181(CONNECTED) 17] create /geekbang 123
Created /geekbang
[zk: localhost:2181(CONNECTED) 18] create /geekbang/time 456
Created /geekbang/time
[zk: localhost:2181(CONNECTED) 19] sync /geekbang/time
Sync is OK
[zk: localhost:2181(CONNECTED) 20] get /geekbang/time
456
[zk: localhost:2181(CONNECTED) 22] stat /geekbang/time
cZxid = 0x51104
ctime = Sun May 05 15:46:28 CST 2024
mZxid = 0x51104
mtime = Sun May 05 15:46:28 CST 2024
pZxid = 0x51104
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

注意

ZAB协议的术语众多,而且有些术语表达的是同一个含义,它们有些在文档中出现,有些在代码中出现,你只有准确理解术语,才能更好地理解ZAB协议地原理。这里补充一些内容。

  • 1.提案(Proposal):进行共识协商地基本单元,可以理解为操作(Operation)或指令(Command),常出现在文档中
  • 2.事务(Transaction):也是指提案,常出现代码中。比如,pRequest2Txn()将接收到的请求转换为事务;再比如,未提交提案会持久化存储在事务日志中。这里需要注意的是,这个术语很容易引起误解,因为它不是指更广泛被接受的含义,具有ACID特性的操作序列,而是仅仅指提案
相关推荐
2401_857636394 分钟前
Spring Boot环境下的知识分类与检索
java·spring boot·后端
小趴菜不能喝8 分钟前
spring boot 3.x 整合Swagger3
java·spring boot·swagger
一叶飘零_sweeeet18 分钟前
Dubbo 构建高效分布式服务架构
分布式·架构·dubbo
微服务技术分享21 分钟前
专为成长型企业打造的Java CRM系统源码:CRM客户关系管理系统技术解析与功能构建
java·crm客户关系管理系统源码·鸿鹄crm客户关系管理系统·鸿鹄crm客户关系管理系统源码
琪露诺大湿22 分钟前
JavaEE-多线程初阶(4)
java·开发语言·jvm·java-ee·基础·1024程序员节·原神
Java程序员-小白30 分钟前
Spring Shell——快速构建终端应用,自定义终端命令
java·后端·spring
想做白天梦35 分钟前
LeetCode :150. 逆波兰表达式求值(含求后缀表达式和中缀转后缀表达式)
java·前端·算法
远望樱花兔39 分钟前
【d63】【Java】【力扣】141.训练计划III
java·开发语言·leetcode
九圣残炎41 分钟前
【从零开始的LeetCode-算法】3254. 长度为 K 的子数组的能量值 I
java·算法·leetcode
孤蓬&听雨43 分钟前
RabbitMQ自动发送消息工具(自动化测试RabbitMQ)
分布式·测试工具·自动化·rabbitmq·自动发送消息