读书笔记丨理解和学习事务,让你更好地融入云原生时代

发布者:三月阳春 2023-5-16 01:05

本文分享自华为云社区《理解和学习事务,让你更好地融入云原生时代-云社区-华为云》,作者: breakDawn。

随着云原生的概念越来越火,服务的架构应该如何发展和演进,成为很多程序员关心的话题。大名鼎鼎的《深入理解java虚拟机》一书作者于21年推出了新作《凤凰架构》,从这本书中可以看到当前时下很多最新的技术或者理念。

因此本文以及后续都将持续沉淀发布这本书的学习笔记和思考,也欢迎购买该书进行详细学习,或者关注后续的学习笔记内容发布,了解精华内容和总结思考。

事务处理

事务有四个经典的特性ACID:

原子性 (Atomicity):事务中的所有操作都必须是原子的,即不可分割或撤销的。在一个事务执行期间,所有的操作都必须同时成功或同时失败,不存在中间状态。一致性 (Consistency):事务执行的结果必须保证数据库的一致性,即数据库中的数据必须在事务开始和结束时保持一致。隔离性 (Isolation):事务之间的操作相互隔离,即一个事务的操作不会受到其他事务的影响。可用性 (Availability):事务执行期间数据库必须保持可用,即可以在任何时候进行访问和修改。

这四个特性ACID中, C其实是目的, AID是手段。只靠内部(单数据源)可以用AID实现C,但是外部(多数据源)的情况下没法用AID保证C。

1 本地事务

本地事务是一种最基础的事务解决方案,适用单个服务使用单个数据源的场景。
(注意,对于MyISAM来说,代码层面调用的rollback其实是空操作,引擎内置了事务处理,不需要代码调用rollback)

本地事务的实现原理来自ARIES(基于语义的恢复与隔离算法)

1.1 本地事务如何实现原子性和持久性

本地事务中, 写入磁盘的过程可能不是原子的,是会崩溃的。
因此要考虑2个异常情况:

未提交事务(调用事务的应用层代码未返回成功),数据还没改完,写了一半崩溃了,导致数据不一致,非原子性已提交事务(调用事务的应用层代码已经反悔了),但是实际磁盘内容还没写就崩了,导致数据完全没变化,非持久性。

解决方式:

引入commit log, 即将事务对数据的修改先写入commit log,写入成功代表事务成功,写入完成后再写磁盘,如果中途崩溃了就重新写入,等同于熟知的redo-log!

这也是为什么redo-log中是针对某个物理块的修改,目的就是能正确重新,不用考虑我写到哪个位置了,直接全部重刷即可。

但是这样性能太慢,希望能在事务提交完成前提前写入磁盘,但是提前写的话可能会非原子。
这时候就可以引入 undolog, 即触发回滚时,可以讲已操作的数据进行undo回滚操作。
这也是为什么undo-log记录的是一条条不可重复执行的语句。

文中还提了2个特征:

NO-FORCE:事务提交后,不强求立刻全部写入磁盘,可以延迟(commit-log,有这的存在就不着急了)STEAL:事务提交前,可以先写入一部分数据(undo-log)

1.2 本地事务如何实现隔离性

隔离性主要就是依赖 数据库锁和数据库隔离级别实现。书中用作者自己的话简述了一遍从 可串行化 到 可重复读 到 读已提交 到读未提交的 演变过程和实现原理, 也提了以下MVCC等内容。

看完后感觉和我这篇文章讲的内容基本对的上:将数据库9种锁、3种读、4种隔离级别一次性串联起来,用15张图呈现背后数据库事务背后的并发原理-云社区-华为云里面有几句比较重要的话:

MYSQL/Innodb的“可重复读级别”只能在“只读”事务中解决幻读问题,但是读写事务还是会幻读读未提交仍然是包含了写锁的。MVCC只是针对读+写的场景做了优化, 如果是写+写是没法优化的,只能用锁。范围锁不是指对范围内的每一条记录加锁, 而是整个范围内甚至都不能做插入了,即包含了间隙的锁。

2 全局事务

这里的全局事务指的是 单个服务 使用多个数据源。核心在于是单个服务,不涉及多服务之间的关联, 视角只有单服务。

XA接口是双向的,能在一个事务管理器和多个资源管理器之间形成通信桥梁,协调多个数据源的一致动作,实现全局事务的统一提交和回滚。Java基于XA接口衍生出的API叫做JTA(javax.transaction.TrancsactionManager和 XAResource)

注意对于全局事务,调用XA的应用者是可以不需要额外处理的,XA会协助做好以下全局事务的响应操作。

2.1 2PC协议(两阶段提交)

准备阶段

数据源将需要做的事务操作记录在redolog中,完成了持久化,并仍旧持有锁,保持隔离性

提交阶段

协调者收到了所有数据源的回应后, 给所有数据源发送commit指令,如果有任一失败或者超时,则发送abort回滚指令。

2PC的缺点:

协调者单点问题:协调者挂了其他的数据源都会一直在持有锁的情况下等待准备阶段的性能问题:整个过程将被最慢的那个数据源所拖累,包括如果连接超时也会影响,导致多余的回滚操作一致性风险:指令丢失、数据源机器崩溃且无法恢复(FLP不可能原理:如果岱机后无法恢复,那么没有任何分布式协议可以达成一致性)

2.2 3PC协议

为了解决上面的单点问题和 准备阶段的性能问题,引入3PC协议
将准备阶段扩展为:

CanCommit询问阶段

这个阶段就是为了确认各机器是否还是正常的,如果经过确认都是正常负载的状态,再下发事务操作,这样就能避免被网络超时、不良负载拖累的风险

PreCommit预提交阶段

和之前一样,下发事务后各数据源写入重做日志

DoCommit阶段

这个过程有一个优化, 如果协调者挂了, 数据源迟迟无法收到,就会默认进行事务提交(注意并非默认回滚),3PC仍然存在网络问题导致的一致性问题。

3 共享事务

书里说这个不常用,不写了,类似于提供共享的数据连接给不同进程使用,使用同一个事务逻辑

4 分布式事务

4.1 CAP理论

C一致性: 各节点同一时刻响应结果一致(数据一致)A可用性: 各节点随时随地都要能正常响应,不能存在延迟或者阻塞的情况(快速响应)P分区容忍性:某个节点挂了,其他节点能代替服务

科学家证明CAP只能同时满足2个

放弃分区容忍性P: 意味着分布式系统不成立。这种情况只有类似于Oracle RAC这种数据通过磁盘共享的情况, 虽然是多个实例,但不算分布式。 基本是分布式系统一定都会包含P,否则没有考虑分布式事务的意义放弃可用性A: 这样可能因为数据同步过程的延迟或者超时,造成系统长时间不可用, 这是不能容忍的放弃一致性C: 数据有短暂不一致的响应。 放弃C是当前分布式系统的主流选择。 一般都是允许数据在中间过程出错, 但允许在输出时能够修正古来。 因此我们放弃了强一致性,追求“最终一致性”

4.2 BASE(可靠性队列)

BASE指 基本可用性 + 柔性事务 + 最终一致性, 或者叫做最大努力交付

实现原理是引入一个消息队列,当某个事务动作发生异常时, 在轮询阶段不断重试,直到成功

要求满足幂等性

可靠性事件队列只要第一步完成了,后续就没有失败回滚的概念,只许成功,不许失败。

4.3 TCC事务

TCC用于解决BASE中无法解决的隔离性问题,因为BASE不允许失败,一定会执行,如果涉及了超售等问题将无法解决。

Try: 尝试执行阶段, 会先进行业务可执行的检查,并提前预留好需要扣除的资源(类似于冻结那一块资源,但没有实际去扣)Confirm:执行阶段,这个过程不再做任何检查,直接执行。如果网络出错等缘故则一直重试,符合幂等Cancel:执行完成,释放try阶段中预留的业务资源,也要符合幂等。

和2PC很类似,但TCC是在用户应用代码层面实现的,业务侵入性很高, 而2PC是基础设施层面提供的。

4.4 SAGA事务

TCC中的缺点在于 try阶段和cancel阶段依赖用户代码实现,但如果你的业务不支持这种操作就麻烦了,比如扣款动作是某个银行做的, 他不支持预扣款的功能。

SAGA会把事务拆成很多个小事务T,按顺序执行, 并根据情况给事务T失败时选择是继续重试T, 还是用补偿事务C来替代重试

这样像银行无法预扣款也无法撤销转账的问题,可以改成自己系统来做中间者做转账操作。

也要引入SAGAlog机制避免长串事务执行过程中崩溃

总结

其实学习本文时,更重要的是思考为什么要学习这么多的事务概念和原理。在云原生时代。

像华为云提供的很多数据库类型的云服务也都支持了分布式事务的能力,例如

华为云RDS分布式事务(https://support.huaweicloud.com/bestpractice-ddm/ddm_01_0004.html):
基于2PC原理实现的MSDTC分布式事务协调器华为云DDM事务模型(https://support.huaweicloud.com/bestpractice-ddm/ddm_01_0004.html):
这里面的分布式事务模块基于 MySQL XA 协议实现,XA 协议是对 2PC(Two Phase Commit) 事务模型的一种实现。华为云DWS分布式事务(https://support.huaweicloud.com/twp-dws/dws_11_0021.html):
基于强一致性的CSN事务机制,使用GaussDB分布式框架下的一个组件GTM以及从中获取到的CSN值来处理事务。

毕竟云原生应用程序通常由多个微服务组成,因此需要在微服务之间进行通信,并保证事务的一致性。在这种情况下,就需要一种适用业务场景的分布式事务解决方案。比如TCC可以在微服务之间实现分布式事务的ACID特性,而且相对于其他方案,TCC更轻量级,对性能影响更小,但其他方案也有各自的适应场景。

因此,分布式事务与云原生技术有很强的关联,可以帮助云原生应用程序实现高效的分布式事务处理。当使用某个关系型数据库产品时,关注他们的分布式事务处理能力并分析是否适合自己当前的业务场景,是非常重要的,也是本书该章节值得学习的一个理由。

关注#华为云开发者联盟# 点击下方,第一时间了解华为云新鲜技术~

华为云博客_大数据博客_AI博客_云计算博客_开发者中心-华为云

推荐阅读
  • 一定要多读书,大量读书,这个万能读书笔记模板真是太好用了!

    一定要多读书,大量读书,这个万能读书笔记模板真是太好用了!

    社会在不断地发展,信息化时代,虽然各行各业变得内卷,让我们的压力变大,但另一方面,很多的知识只要我们想学,都能在书中找到答案。掌握读书的方法,也是我们必须要具备...

    12-14

  • 一定要大量读书,分享一个万能读书笔记。

    一定要大量读书,分享一个万能读书笔记。

    万能读书笔记:开启深度阅读之旅在阅读的广袤世界里,一本好的读书笔记如同一位忠实的伙伴,陪伴我们在知识的海洋中畅游,助我们更好地汲取书中的智慧与精华。以下是一种万...

    11-21

  • 适合普通人:一个超好用的读书笔记法。

    适合普通人:一个超好用的读书笔记法。

    超好用的读书笔记法:开启阅读智慧之门在这个信息爆炸的时代,阅读成为了我们获取知识、开阔视野的重要途径。然而,如何将书中的知识真正内化为自己的智慧,读书笔记法就显...

    11-17

  • 读书笔记:《我的前半生》

    读书笔记:《我的前半生》

    当合上这本书,为生活在那个时代的底层苦难大众所悲痛,为那些因一己之私而出卖人格和国家主权的罪恶势力所痛恨,为溥仪从皇帝到公民的人生经历所理解之同情,但更萦绕脑海...

    11-15

  • 《成功不看其他,关键看思维》读书笔记

    《成功不看其他,关键看思维》读书笔记

    #聚光创作大赛##以书之名##我在岛屿读书#书名:逆向思维文章:成功不看其他,关键看思维作者:卜翔宇精彩句段:想要做成一件事,不看你有没有好的身份,也不看你有没有经验...

    11-15

  • 读书笔记10: 一定要大量看书

    读书笔记10: 一定要大量看书

    没有手机之前,我的爱好之一就是看纸质稿的书。自己的钱,大部分都用来买书了。学校图书馆也借了不少,那时候街上还有租书的门铺,每周都要去租书的店铺去租。以前看书比较...

    11-08

  • 《留一线,是给别人也是给自己》读书笔记

    《留一线,是给别人也是给自己》读书笔记

    #聚光创作大赛##以书之名##长文创作激励计划#书名:逆向思维文章:留一线,是给别人也是给自己作者:卜翔宇精彩句段:有一句话是“狭路相逢勇者胜”,说的是与人竞争或对决...

    11-08

  • 一定要大量看书:3个超好用的读书笔记写作法

    一定要大量看书:3个超好用的读书笔记写作法

    早起|运动|阅读|写作|复盘|冥想▫️文字字数1400字▫️预计阅读需3分钟你好,我是精进自我管理的小雪❄️很多喜欢阅读的小伙伴,产生的困惑,如读了大量的书,记不住...

    11-07

  • 掌握四种做读书笔记的方法,助你把读过的书变为精神财富

    掌握四种做读书笔记的方法,助你把读过的书变为精神财富

    日本作家奥野宣之在《如何有效阅读一本书》中,告诉我们,只有完整执行选书、购书、读书、记录、活用这五个流程,才能叫做有效阅读了一本书。这里的所说的“记录”,就是做...

    10-29

  • 常用常新的5个读书笔记小技巧

    常用常新的5个读书笔记小技巧

    你好呀,我是白杨。关于读书,就像卢梭说的:“读书不要贪多,而是要多加思索,这样的读书使我获益不少。”所以在看某些书时,我是很喜欢做读书笔记的。一边看一边做笔记的...

    10-29

阅读排行

Copyright © 2021-2024 领读者 All Rights Reserved.

本网站提供好文章在线阅读,经典好文章推荐好文章摘抄日志随笔等各种文章应有尽有。

蜀ICP备09043158号-3