Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ZooKeeper如何保证事务原子性?

ZooKeeper如何保证事务原子性?

作者头像
并发笔记
发布于 2022-11-21 12:16:32
发布于 2022-11-21 12:16:32
1K00
代码可运行
举报
文章被收录于专栏:并发笔记并发笔记
运行总次数:0
代码可运行

先解答疑惑,题主对ZAB理解是正确的。为了便于描述,本文将事务理解为具有ACID的一组操作,一个ZooKeeper请求(例如:create)称之为提案。

ZAB协议是共识算法的一种,共识算法仅能保证单个提案在集群中达成共识,如果是多个提案要保证事务的话,需要在上层再做一次封装。ZAB被称为原子广播协议,也是做了这一层封装,即:multi命令。

multi命令让多个提案,要么同时成功,要么同时失败,所以要知道ZooKeeper怎么处理事务的,只需要关注multi命令的实现即可。

ZooKeeper对提案的协商,是以责任链的形式处理,下图是协商提案的责任链路,大家可以参考。

不难发现,客户端的请求,先到达PrepRequestProcessor,那么在PrepRequestProcessor一定可以找到对multi命令的特殊操作。

以下代码为PrepRequestProcessor#pRequestHelper,我省略掉了try-catch和其他无关代码,在处理multi请求时,ZooKeeper会先遍历multiRequest,把每个元素当做一个单独的提案调用pRequest2Txn()方法来协商,当某个提案协商发生异常时,ZooKeeper会调用rollbackPendingChanges()回滚正在执行中的提案。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// PrepRequestProcessor
private void pRequestHelper(Request request) throws RequestProcessorException {
	switch (request.type) {
	case OpCode.multi:
		MultiOperationRecord multiRequest = new MultiOperationRecord();
		try {
			ByteBufferInputStream.byteBuffer2Record(request.request, multiRequest);
		} catch (IOException e) {
			request.setHdr(new TxnHeader(request.sessionId, request.cxid, zks.getNextZxid(), Time.currentWallTime(), OpCode.multi));
			throw e;
		}
		List<Txn> txns = new ArrayList<Txn>();
		long zxid = zks.getNextZxid();
		KeeperException ke = null;

		Map<String, ChangeRecord> pendingChanges = getPendingChanges(multiRequest);
		request.setHdr(new TxnHeader(request.sessionId, request.cxid, zxid,
				Time.currentWallTime(), request.type));

		for (Op op : multiRequest) {
			Record subrequest = op.toRequestRecord();
			int type;
			Record txn;
			if (ke != null) {
				type = OpCode.error;
				txn = new ErrorTxn(Code.RUNTIMEINCONSISTENCY.intValue());
			} else {
				try {
					pRequest2Txn(op.getType(), zxid, request, subrequest, false);
					type = op.getType();
					txn = request.getTxn();
				} catch (KeeperException e) {
					ke = e;
					type = OpCode.error;
					txn = new ErrorTxn(e.code().intValue());

					if (e.code().intValue() > Code.APIERROR.intValue()) {
						LOG.info("Got user-level KeeperException when processing {} aborting"
								 + " remaining multi ops. Error Path:{} Error:{}",
								 request.toString(),
								 e.getPath(),
								 e.getMessage());
					}

					request.setException(e);

					/* Rollback change records from failed multi-op */
					rollbackPendingChanges(zxid, pendingChanges);
				}
			}

			try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
				BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
				txn.serialize(boa, "request");
				ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
				txns.add(new Txn(type, bb.array()));
			}
		}
		request.setTxn(new MultiTxn(txns));
		if (digestEnabled) {
			setTxnDigest(request);
		}
		break;
}

回到问题本身,使用multi命令,创建一个节点和删除一个节点时,当创建节点成功了,但是删除节点失败了,那么ZooKeeper会回滚创建操作。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 并发笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入浅出Zookeeper源码(六):客户端的请求在服务器中经历了什么
当我们向zk发出一个数据更新请求时,这个请求的处理流程是什么样的?zk又是使用了什么共识算法来保证一致性呢?带着这些问题,我们进入今天的正文。
泊浮目
2023/12/25
2500
ZooKeeper源码分析:Quorum请求的整个流程
Quorum请求是转发给Leader处理,并且需要得一个Follower Quorum确认的请求。这些请求包括:
星哥玩云
2022/07/04
6730
ZooKeeper源码分析:Quorum请求的整个流程
一起读源码之zookeeper(1) -- 启动分析
从本文开始,不定期分析一个开源项目源代码,起篇从大名鼎鼎的zookeeper开始。 为什么是zk,因为用到zk的场景实在太多了,大部分耳熟能详的分布式系统都有zookeeper的影子,比如hbase
JadePeng
2018/03/12
2K0
一起读源码之zookeeper(1) -- 启动分析
zookeeper源码分析(3)— 一次会话的创建过程
在一次会话的创建过程中,需要客户端首先发送创建会话请求,服务端集群创建会话成功后会将响应发送给客户端。
Monica2333
2020/06/22
1.7K0
深入分析 Watcher 机制的实现原理(二)服务端接收请求处理流程
firstProcessor 的 初 始 化 是 在 ZookeeperServer 的setupRequestProcessor 中完成的,代码如下
周杰伦本人
2022/10/25
4000
深入分析 Watcher 机制的实现原理(二)服务端接收请求处理流程
Apache ZooKeeper - 集群中 Leader 的作用_事务的请求处理与调度分析
Leader 服务器在 ZooKeeper 中的作主要是处理事务性的会话请求以及管理 ZooKeeper 集群中的其他角色服务器
小小工匠
2021/08/17
4870
深入浅出Zookeeper源码(五):BadVersionException到底是怎么一回事
最近在开发时偶尔会观测到zk报出BadVersionException,后在搜索引起上得知了是乐观锁相关的问题,很快就解决了问题。不过学而不思则罔:无论是单体应用还是分布式系统,在运行过程中总要有一种机制来保证数据排他性。接下来,我们就来看看zk是如何实现这种机制的。
泊浮目
2023/12/25
1450
Zookeeper源码分析:Watcher机制
1. 设置Watcher 使用Watcher需要先实现Watcher接口,并将实现类对象传递到指定方法中,如getChildren, exist等。Zookeeper允许在构造Zookeeper对象时候指定一个默认Watcher对象.getChildren和exit方法可以使用这个默认的Watcher对象,也可以指定一个新Watcher对象。
星哥玩云
2022/07/04
2660
Zookeeper源码分析:Watcher机制
Zookeeper——Watcher原理详解
Zookeeper引入了Watcher机制来实现分布式数据的发布/订阅功能,使得多个订阅者可以同时监听某一个主题对象,当主题对象自身状态发生改变时,就会通知所有订阅者。那么Zookeeper是如何实现Watcher的呢?要了解其中的原理,那必然只能通过分析源码才能明白。
夜勿语
2020/09/07
1.7K0
进阶分布式系统架构系列:Zookeeper 监听机制
当今时代,发布订阅场景到处可见,像微信中的公众号消息订阅,或者网购场景下库存消息的订阅通知等等,这些都是属于发布订阅的场景。
民工哥
2023/08/25
4890
进阶分布式系统架构系列:Zookeeper 监听机制
Zookeeper-watcher机制源码分析(二)
其大致流程如下   ① 通过传入的path(节点路径)从watchTable获取相应的watcher集合,进入②
Java架构
2018/08/09
5980
Zookeeper-watcher机制源码分析(二)
Zookeeper 通知更新可靠吗? 解读源码找答案!
遇到Keepper通知更新无法收到的问题,思考节点变更通知的可靠性,通过阅读源码解析了解到zk Watch的注册以及触发的机制,本地调试运行模拟zk更新的不可靠的场景以及得出相应的解决方案。
特鲁门
2018/07/17
3.4K12
ZooKeeper-数据读写流程
作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
运维小路
2025/05/12
490
ZooKeeper-数据读写流程
Apache ZooKeeper - 集群中 Observer 的作用以及 与 Follow 的区别
在 ZooKeeper 集群服务运行的过程中,Follow 服务器主要负责处理来自客户端的非事务性请求,其中大部分是处理客户端发起的查询会话等请求。而在 ZooKeeper 集群中,Leader 服务器失效时,会在 Follow 集群服务器之间发起投票,最终选举出一个 Follow 服务器作为新的 Leader 服务器。
小小工匠
2021/08/17
1.6K0
深入浅出Zookeeper源码(七):Leader选举
对于一个分布式集群来说,保证数据写入一致性最简单的方式就是依靠一个节点来调度和管理其他节点。在分布式系统中我们一般称其为Leader。
泊浮目
2023/12/25
2990
画图搞懂集群模式下zookeeper的ZAB协议如何保证数据一致性
zookeeper能被各个牛逼的中间件项目中所依赖,已经说明了他的地位。一出手就是稳定的杀招。zookeeper是什么?官网中所说,zookeeper致力于开发和维护成为一个高度可靠的分布式协调器。
简熵
2023/03/06
5390
画图搞懂集群模式下zookeeper的ZAB协议如何保证数据一致性
zookeeper源码分析(6)-数据和存储
在Zookeeper中,数据存储分为两部分:内存数据存储和磁盘数据存储。本文主要分析服务器启动时内存数据库的初始化过程和主从服务器数据同步的过程。在此之前介绍一些数据存储涉及的基本类。 DataTree Zookeeper的数据模型是一棵树,DataTree是内存数据存储的核心,代表了内存中一份完整的数据(最新),包括所有的节点路径,节点数据和ACL信息,对应watches等。类的主要属性为:
Monica2333
2020/06/22
1.9K0
ZooKeeper Watcher机制(源码分析)
Zookeeper客户端和服务端在交互时,并不会将Watcher实体发送给服务端,这样减少了服务端的内存消耗,并且提高了传输效率,这部分可以通过Packet的序列化代码(Packet中的createBB方法)可以看出,如下:
shysh95
2019/07/24
1.1K0
Apache ZooKeeper - ZK的数据和文件
本篇博文,我们主要聚焦在ZooKeeper 程序运行期间,都会处理哪些数据,以及他们的存储格式和存储位置。
小小工匠
2021/08/17
1K0
Zookeeper之FileTxnSnapLog源码分析
FileTxnSnapLog包含了PlayBackListener内部类,用来接收事务应用过程中的回调,在Zookeeper数据恢复后期,会有事务修正过程,此过程会回调PlayBackListener来进行对应的数据修正。其源码如下 
tunsuy
2022/10/27
2580
推荐阅读
相关推荐
深入浅出Zookeeper源码(六):客户端的请求在服务器中经历了什么
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验