etcd 实战课
唐聪
腾讯云资深工程师,etcd 活跃贡献者
28449 人已学习
新⼈⾸单¥59
登录后,你可以任选3讲全文学习
课程目录
已完结/共 28 讲
开篇词 (1讲)
etcd 实战课
15
15
1.0x
00:00/00:00
登录|注册

09 | 事务:如何安全地实现多key操作?

隔离性
一致性
原子性与持久性
隔离性
持久性
一致性
原子性
etcd提供可重复读、串行化快照隔离级别的事务,保障并发事务场景中数据安全性
事务中缺少对Bob账号资产是否发生变化的判断,导致资产凭空消失
etcd通过MVCC写事务持有boltdb写锁,保证事务未成功执行和持久化任意数据到磁盘上
etcd基于MVCC机制、boltdb事务实现可重复读、串行化快照隔离级别的事务,保障并发事务场景中数据安全性
数据不丢失
通过数据库和业务应用程序相互协作完成
etcd基于WAL日志、consistent index、boltdb的事务能力提供支持
ACID特性
事务
隔离性
一致性
原子性与持久性
隔离性
持久性
一致性
原子性
脑图
ACID特性
事务
总结

该思维导图由 AI 生成,仅供参考

你好,我是唐聪。
在软件开发过程中,我们经常会遇到需要批量执行多个 key 操作的业务场景,比如转账案例中,Alice 给 Bob 转账 100 元,Alice 账号减少 100,Bob 账号增加 100,这涉及到多个 key 的原子更新。
无论发生任何故障,我们应用层期望的结果是,要么两个操作一起成功,要么两个一起失败。我们无法容忍出现一个成功,一个失败的情况。那么 etcd 是如何解决多 key 原子更新问题呢?
这正是我今天要和你分享的主题——事务,它就是为了简化应用层的编程模型而诞生的。我将通过转账案例为你剖析 etcd 事务实现,让你了解 etcd 如何实现事务 ACID 特性的,以及 MVCC 版本号在事务中的重要作用。希望通过本节课,帮助你在业务开发中正确使用事务,保证软件代码的正确性。

事务特性初体验及 API

如何使用 etcd 实现 Alice 向 Bob 转账功能呢?
在 etcd v2 的时候, etcd 提供了 CAS(Compare and swap),然而其只支持单 key,不支持多 key,因此无法满足类似转账场景的需求。严格意义上说 CAS 称不上事务,无法实现事务的各个隔离级别。
etcd v3 为了解决多 key 的原子操作问题,提供了全新迷你事务 API,同时基于 MVCC 版本号,它可以实现各种隔离级别的事务。它的基本结构如下:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

etcd事务通过MVCC机制和boltdb的写原理,保证了事务的原子性和持久性,同时提供了各种隔离级别的事务,确保了数据的一致性和可靠性。在etcd v3中,引入了全新的迷你事务API,通过If、Then、Else语句实现了灵活的比较功能。事务的执行流程经过ApplyCompares、ApplyTxn/Then和ApplyTxn/Else操作,通过MVCC层的读写事务对象执行各操作。etcd通过WAL日志和consistent index、boltdb事务特性,去确保事务的原子性,避免资金凭空消失、新增。在转账案例中,事务的一致性被破坏的根本原因是缺少对账号资产变化的判断。为了确保事务的一致性,业务程序需要检查转账者资产,并通过账号资产的版本号确保双方账号资产未被其他事务修改。隔离性是指事务在执行过程中的可见性,etcd通过MVCC机制实现读写不阻塞,并解决脏读的问题。已提交读存在不可重复读的问题,可通过MVCC快照读或etcd的事务框架STM实现可重复读。串行化快照隔离是通过快照技术实现的类似串行化的效果,事务提交时能检查是否冲突。总的来说,etcd事务通过MVCC机制和boltdb的写原理,保证了事务的原子性和持久性,同时提供了各种隔离级别的事务,确保了数据的一致性和可靠性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《etcd 实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • 云原生工程师
    老师分析得透彻,学习了,原来自己平时使用的事务过程中,无意间已经使用了串行化快照隔离级别,还请问一下事务性能相比put接口差异大吗

    作者回复: 嗯,肯定有不少差异的,事务执行逻辑更复杂,影响性能的因素比较多,实践篇我有介绍,建议根据自己实际业务场景,部署环境,使用etcd自带的benchmark工具压测对比下差异.

    2021-02-10
    5
  • WGJ
    老师,有个问题就是 在原子性和持久性介绍当中,假如在WAF日志已经提交成功了,执行事务的时候发生了crash,这时候我理解的返回给client是失败的,那么当执行WAF重放日志的时候,该事务又成功了;换句话说,事务操作 返回给client 结果 的时机是什么时候呢,是写 WAF日志成功就返回呢,还是等待事务提交之后才返回呢

    作者回复: 返回给client的结果时机可参考03节写流程架构图中第10步,apply成功的时候,会通过管道通知给相应的goroutine, 告知写入结果,然后返回给client。如果事务执行过程中crash了,这时client看到的应该是超时错误,超时意味着,可能写入成功,可能写入失败,业务自己重试时需要进行相应的检查、确保幂等性。

    2021-02-19
    2
  • Geek_604077
    在数据库事务中,有各种各样的概念,比如脏读、脏写、不可重复读与读倾斜、幻读与写倾斜、更新丢失、快照隔离、可串行化快照隔离? 你知道它们的含义吗? 脏读、脏写: 在读未提交的隔离级别的情况下,事务A执行过程中,事务A对数据资源进行了修改,事务B读取了事务A修改后且未提交的数据。A因为某些原因回滚了操作,B却使用了A对资源修改后的数据,进行了读写等操作。 不可重复读: 在读未提交、读提交的隔离级别情况下,事务B读取了两次数据资源,在这两次读取的过程中事务A修改了数据,导致事务B在这两次读取出来的数据不一致。这种在同一个事务中,前后两次读取的数据不一致的现象就是不可重复读。 幻读: 在可重复读得隔离级别情况下,事务B前后两次读取同一个范围的数据,在事务B两次读取的过程中事务A新增了数据,导致事务B后一次读取到前一次查询没有看到的行。 读倾斜、写倾斜: 读写倾斜是在数据分表不合理的情况下,对某个表的数据存在大量的读取写入的需求,分表不均衡不合理导致的。 更新丢失: 第一类丢失,在读未提交的隔离级别情况下,事务A和事务B都对数据进行更新,但是事务A由于某种原因事务回滚了,把已经提交的事务B的更新数据给覆盖了。这种现象就是第一类更新丢失。 第二类丢失,在可重复读的隔离级别情况下,跟第一类更新丢失有点类似,也是两个事务同时对数据进行更新,但是事务A的更新把已提交的事务B的更新数据给覆盖了。这种现象就是第二类更新丢失。 快照隔离: 每个事务都从一个数据库的快照中读数据,如果有些数据在当前事务开始之后,被其他事务改变了值,快照隔离能够保证当前事务无法看到这个新值。 可串行化快照隔离: 可串行化快照隔离是在快照隔离级别之上,支持串行化。 (讲得特别好,肯定花了特别多的心思跟时间,肯定掉了好多头发🐶,给老师点赞)
    2022-02-15
    1
    12
  • warm
    觉得可串行快照读讲的不是很详细还是我理解不到位。是每次执行事务都要先拿到读写锁还是在检测冲突重试才加读写锁?如果是前者根本没必要做冲突检测
    2023-08-21归属地:广东
    1
  • types
    关于事务txn,请问事务都是在leader执行的嘛?还是根据request中的动作决定?
    2021-09-25
    1
  • 黄堃健
    老师,在etcd看来,写事件时,先获取数据,然后获取mvcc的读写锁,获取锁之后,再次读取数据,比较符合预期,最后更新数据。 看上去不像是乐观锁。 更像悲观锁
    2024-03-19归属地:广东
  • akiqiu
    感觉可串行化的SSI有点牵强呢?看上去是用户手工来实现了SSi,而不是etcd自己实现了SSI。而且通过读代码,发现所有写操作在获取batchTx后都会LockInsideApply,是一个独占锁,所以看上去写操作是串行的,所以写事务应该也是串行的?我感觉是严格的串行执行写操作实现了可串行化。correct me if i'm wrong
    2024-02-19归属地:广东
  • akiqiu
    请问etcd存在写-写并发冲突吗?因为并发写请求经过raft后,应该已经被整理成顺序执行的一个个条目,交给状态机串行地去apply了。这样在存储层还存在写-写并发冲突吗?
    2024-02-19归属地:广东
  • Hugh
    在快照串行化隔离的案例里面,有个问题想请教一下,首先冲突检测机制是在提交前进行检测的,那么意味着无论提交是否成功,大部分的节点都已经写入了raft log或者WAL,假设这次检测的结果是失败的(比如已经没有足够的钱进行转账),那么就不会提交了(给客户端的反馈也是此次转账失败)。 这个时候leader节点突然宕机,其他节点重新开始了选举,那些已经写入此次转账log的节点是有可能成为新的leader,在新的任期中,仍然会尝试提交这次事务,假设这次提交时已经有了足够的金额,则会导致提交成功。但是这次的提交成功对于客户端来说完全不感知,这样子就会导致用户发现自己的金额突然变少了,这个肯定是不符合预期的,老师可以解释一下这中间是不是有哪部分我的理解有问题呢
    2022-06-21
  • 🤔
    etcd事务可用在分布式事务吗?
    2022-02-15
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部