18|分布式事务:如何同时保证分库分表、ACID和高性能?
该思维导图由 AI 生成,仅供参考
前置知识
两阶段提交
- 深入了解
- 翻译
- 解释
- 总结
分布式事务是分库分表或微服务架构中的挑战之一。本文介绍了分布式事务中常用的协议,包括两阶段提交、三阶段提交和XA事务。两阶段提交协议通过准备和提交阶段保证事务一致性和可靠性,但存在节点阻塞和单点故障等缺点。三阶段提交协议引入CanCommit阶段,减少了事务失败的可能性。XA事务是将两阶段提交协议具象化的标准。文章还提到了面试中可能涉及的问题和准备工作,包括跨库事务、分布式事务方案和数据一致性等。读者可以通过学习本文内容,了解分布式事务的常用协议和面试准备相关知识,提高对分布式事务的理解和应对能力。 TCC、AT和SAGA是追求最终一致性的分布式事务解决方案,分别强调业务自定义逻辑、反向补偿和生成数据库反向操作。容错和禁用跨库事务也是讨论的重点。文章还介绍了禁用跨库事务和延迟事务的解决方案,以及面试思路和技巧。总体而言,本文全面介绍了分布式事务的协议、解决方案和面试准备,对于从事分布式系统开发和面试准备的读者具有重要参考价值。
《后端工程师的高阶面经》,新⼈⾸单¥59
全部留言(11)
- 最新
- 精选
- ZhiguoXue_IT业界内落地实用基本都是mq保证最终一致性,但是据说银行系统是强一致性,作者认为呢
作者回复: 我持怀疑态度。我个人理解,分布式事务里面,如果事务协调者,事务参与者没有什么 redo 和 undo log 之类的东西,我个人认为它们不可能达成强一致性。但是问题又来了,事务协调者还要考虑 ACID 中的 AID 问题,不仅仅是一致性。举个例子,在意图保证强一致性的场景里面,你要不要考虑隔离性的问题?一个分布式事务能不能看到另外一个分布式事务的修改? 所以,综合来说,我持怀疑态度。之前听过一点银行的技术分享,他们说的强一致性其实都是最终一致性,总是有不一致的问题。也可能是我孤陋寡闻了。
2023-07-26归属地:北京2 - 锅菌鱼saga的反向补偿和AT的undolog是差不多的吧?
作者回复: 我看起来是差不多,我觉得 AT 就是一种在 SQL 层面上的 SAGA。个人观点。
2023-10-20归属地:广东1 - 程序猿佬鸟老师您好: Q1: 延时事务在分库分表中间件中有实现吗? 您能具体说一个方向吗? 看完您这章我有点蒙圈了
作者回复: 我以前写过的分库分表中间件就有这一个策略。开源的话,我记得 GO 中的 vitess 好像就是这么搞的。至于具体的分库分表的代理如 mycat 之类的,我就不太记得了。
2024-01-28归属地:中国香港 - Geek_3d0fe8那个TCC如果confirm失败了,为什么只能进行重试呢? 调 cancel 不行吗
作者回复: 你可以调 cancel,但是问题在于,万一一部分人已经 confirm 成功了呢?
2023-12-11归属地:广东2 - sheep延迟事务有哪些中间件实现了呢?实际开发中要操作的话,我们该怎么操作
作者回复: 基本上分库分表中间件都会实现吧,因为这是最简单的事务形态了。 实际中你就用装饰器,装饰不同 DB 的事务。然后当要执行操作的时候,你就看看有没有开事务,没有你就开事务,有了你就直接用已有的事务。
2023-11-08归属地:广东 - sheep老师这里有几个问题[嘿嘿] 问题1: TCC 另外一个方案中,进行丢掉这个数据,这里图片好像没有看到丢掉这个流程耶 问题2: AT事务下会帮你生成反向操作。有哪些分布式事务中间件支持这种反向操作呀 问题3: 业务A调用业务B,业务A根据业务B的执行情况来确定是继续执行,还是回滚,这种也属于分布式事务么 问题4:并发高的业务,分布式事务频繁失败情况下,会不会导致不一致的情况越来越严重?虽然有自动修复进行缓解。 其他的: “也就是把话题引导到延迟事务这个方案方案上”,是不是多了一个“方案”两个词 “只有db_2上开启的事务用上了”图片这里应该是db_1吧
作者回复: 1. 虽然画了返回响应,但是不是说返回正确响应,而是返回一个异常响应。其实如果你是同步修复的话,你可以修复了之后返回正确顺序 2. 据我了解,seata 是支持的 3. 分布式事务这个词已经被用烂了,所以这里这么说也没错。 4. 如果分布式事务频繁失败,你关心的就不是数据一致性了,你要首先解决频繁失败的问题。正常来说,失败比率都是低于万分之一的。比如说以前我们一天百万的数据,不一致的数据也不到个位数。 db_2 的我没找到,感谢纠正。
2023-11-08归属地:广东 - Geek8004自动故障处理的机制不是很明白.针对这句话“修复数据本身分成两种,一种是用已经提交的数据库的数据来修复没有提交成功的数据库的数据;另外一种则是用没有提交成功的数据库的数据来还原已经提交的数据库的数据。 ”只有一份数据,假如我db1 rollback失败,此时db0之前已经提交了数据,我怎么用已提交的数据修复未提交的?他们数据没有冗余呀
作者回复: 你这个场景我其实没有理解。就是如果 db0 是提交的话,那么 db1 也是提交,不会出现 db0 提交,db1 回顾的场景。 如果 db0 提交成功了,但是 db1 没有提交成功,那么就用 db0 的数据去修复 db1。
2023-08-30归属地:中国香港 - peter请教老师几个问题: Q1:根据文章内容,不管哪种分布式事务解决方案,都做不到ACID,都无法保证不出问题。那么,在实际的应用中,分布式事务的成功率一般能达到多少? Q2:AT是概念还是具体框架? Q3:单库但有分表,是否存在分布式事务? Q4:两个SQL可以共用一个事务,前提是这两个SQL是属于一个Session吗?不同Session的SQL不能共用一个事务吧。 Q5:对数据库进行修复会影响业务吗?如果会影响,会采取哪些措施?
作者回复: 1. 这个要看业务。成功率是一个不够准确的定义,你应该说取得一致性的时间是多长,以及没有办法达成一致的比率有多高。实际上,你应该做到和你的可用性一致。比如说正常,我们都会要求最终不一致的数据,每天应该控制在个位数。太多了你手工修复很要命的。 2. 我个人认为,是 seata 里面引入的。我比较孤陋寡闻,没见着别的地方哟用。我自己理解的话喜欢把它说成是 SAGA 的自动化的特殊形态。 3. 嘿嘿,如果你的分库分表中间件做得好,那么就没有。有些分库分表中间件是语句维度来调度的,所以搞不好也引入了分布式事务。 4. 对的 5. 主要是小心并发。比如说你数据出错了,你准备去修复。但是你修复之前,可能另外一个请求又把错误的数据更新为新数据了,但是这个新数据是对的。所以最好是在修复的时候要根据更新时间、版本号之类的来判断一下,避免出现并发覆盖的问题。
2023-07-27归属地:北京 - 进击的和和老师你好 协调者让参与者执行事务,但是并不提交,协调者返回执行情况 这里是不是参与者返回执行情况呢。 我在两阶段提交那里说到在提交阶段,协调者会不断重试直到把 Commit 请求发送给协调者;协调者如果在提交阶段中途崩溃,也要确定是否需要提交或者回滚。那么你就应该可以理解,在重试成功之前,或者在协调者恢复过来重新提交或者回滚之前,数据是不一致的。这句话好像有点小问题吧。 两阶段提交如果a参与者成功了,b参与者失败了,那么是不是只能人工处理或者有个修复数据的脚步进行修复呢? 关于容错,如果协调者挂了,那么参与者1是否可以询问其他参与者情况呢
作者回复: 1. 是参与者返回执行情况。 2. b 参与者如果在准备阶段就失败了,那么直接回滚,这个应该没什么疑问。问题是在 commit 阶段,如果 b 参与者 commit 失败了怎么办。那么按照两阶段提交协议的要求,b 参与者这时候是不能 commit 失败的,b 要不断重试,或者用别的手段保证自己的成功。但是,显然这也是一个不现实的要求,所以 b commit 最终失败之后,肯定要人工介入的。这你也可以看出来,又出现了不一致。从理论上来说,协调者在发现 b 死活不能提交成功之后,那么 a 提交的数据应该也要处于一种不可用的状态,可惜的是,我们也做不到。 3. 参与者可以考虑询问。但是这里有一个问题,就是你问几个人呢?比如说十个节点里面,你问了六个人,三个人告诉你提交,三个人告诉你不知道,这时候你是提交还是不提交?那三个不知道的,又该怎么办?所以整体这需要一个比较复杂的机制。
2023-07-26归属地:四川 - 程序猿佬鸟延迟事务?sharding JDBC也没有实现啊2024-01-28归属地:中国香港