Saga模式是确保数据一致性的一种方式

你好。在OTUS,他已经为“ Highload Architect”课程的新小组开设了一组课程在这方面,我将继续为该课程专门编写一系列出版物,并邀请您参加有关以下主题的免费演示课:“ MySQL中的索引:最佳实践和陷阱”。您可以在此处注册网络研讨会










介绍



如您所知,从整体架构过渡到微服务架构会导致与项目的技术部分和人为因素相关的许多困难。最困难的技术挑战之一是确保分布式系统的一致性



上一次,我们讨论了微服务体系结构中一致性问题的原因,实现一致性的乐观方法以及使用两阶段提交的一致性。



佐贺花纹



Saga是一种无需使用分布式事务即可确保微服务体系结构中数据一致性的机制。



对于需要在多个服务中更新数据的每个系统命令,将创建一个传奇。传奇是一种“清单”,由顺序的本地ACID事务组成,每个事务在一项服务中更新数据。补偿事务用于处理故障。如果在本地事务已成功完成的所有服务上失败,则执行此类事务。



传奇中有几种交易类型,多达四种:



  • 补偿-撤消本地事务所做的更改。
  • 可退款项是在后续交易失败的情况下需要退款(取消)的交易。
  • 转弯-决定整个传奇成功的交易。如果成功,则传奇故事一定会结束。
  • 可重复-紧随枢轴之后,并确保成功。


您可以使用编排或编排来组织传奇。



对于编舞传奇,没有专用的编排器。以订单服务和用户为例,该订单服务看起来像这样:订单服务接收到一个请求并以PENDING状态创建一个订单,然后发布“已创建订单”事件。用户服务中的事件处理程序将处理此事件,尝试保留项目,然后将结果作为事件发布。订单服务处理此事件,根据读取结果确认或取消订单。



精心编排的传奇看起来更有趣。以上面的服务为例,它看起来可能像这样:订单服务接收到一个请求,创建一个传奇,该传奇创建处于PENDING状态的订单,然后发送命令为用户服务预留商品。用户服务尝试保留产品并发送指示结果的响应消息。英雄传说批准或取消订单。



saga模式允许应用程序跨多个服务维护数据一致性,而无需使用分布式事务(两阶段提交),并且避免了上一篇文章中讨论的问题。但是另一方面,编程模型非常复杂:例如,每个事务的开发人员都必须编写一个补偿性事务,以抵消先前在传奇中所做的更改。



传奇使我们能够实现ACD模型(以ACID术语表示的Atomicity + Consistency + Durability),但是我们丢了一个字母。缺少字母I导致众所周知的缺乏隔离的问题。这些内容包括:丢失的更新-一个英雄传奇覆盖了另一个英雄所做的更改而没有读取它们,脏读-事务或英雄传奇读取了另一个英雄传奇的未完成更新,模糊/不可重复读取)-传奇的两个不同阶段读取了相同的数据,但是由于另一个传奇进行了更改而获得了不同的结果。有许多模式可以让您修复某些异常:语义锁定,交换更新,悲观表示,重新读取值,更改文件和按值。确保隔离的问题仍然悬而未决。



另一个有趣的问题是不可能原子更新数据库并将消息发布到消息代理以触发传奇中的进一步步骤。



结论



我们讨论了使用编排和编排来组织传奇的方法,以及这种模式带来的问题。接下来,我们将讨论解决一些异常并将事务发送到消息代理的方法。






All Articles