微服务架构中的分布式事务

你好。OTUS已经在9月为新课程“ Highload Architect”开设了一组课程在这方面,我将继续为该课程专门编写系列出版物,并邀请您参加我的免费网络研讨会,在其中我将详细介绍OTUS中的课程计划和培训格式。您可以在此处注册网络研讨会








介绍



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



一致性



相当微妙的一点是,分布式系统上下文中的一致性不同于数据库上下文中的一致性。此外,通过一致性,我们将确切地说是第一个:不完整(错误)的操作不会带来任何影响且不会更改数据;在并行访问数据时,如果数据具有多个副本(复制),则所有操作都被视为原子操作(您看不到操作的中间结果)。 ,那么对所有副本应用操作的顺序是相同的。也就是说,实际上,我们希望接收ACID事务,但仅接收分布式事务。



问题的原因



为什么在微服务架构中很难保持一致性?事实是,这种体系结构样式通常涉及每个服务模式对数据库的使用。让我提醒您,此模式在于每个微服务都有其自己独立的一个或多个基础(基础,因为除了主要数据源之外,例如还可以使用缓存)。这种方法一方面不允许在微服务之间添加隐式数据格式链接(微服务仅通过API进行显式交互),另一方面可以充分利用微服务架构的技术优势(例如技术不可知)(我们可以选择适合于微服务上特定负载的数据存储技术)。 )。但是,所有这些使我们失去了数据一致性的保证。自己判断整体与一个大型数据库通信,该数据库提供了提供ACID交易的功能。现在有许多数据库,我们有许多小型ACID交易,而不是一个大型ACID交易。我们的任务是将所有这些交易合并为一个分散的



乐观的一致性



首先想到的是乐观一致性的概念:我们根据需要为任意数量的存储引擎提交任意数量的事务。同时,我们希望一切都会好起来,如果一切不好,那么我们最终会说一切都会好的。如果最后一切都不好,那么我们说:“是的,这确实发生了,但可能性极低。”



开个玩笑,在不重要的情况下忽略一致性是一个好主意,尤其是当您考虑要花多少精力来维护它(我希望您稍后会看到)时。



一致性选项



如果一致性对业务至关重要,则有几种方法可以实现它。如果我们谈论的是一种服务更新数据的情况(例如,存在数据库复制),那么可以应用诸如Paxos或Raft之类的标准一致性算法。这种交易称为同类交易。如果数据是由几种服务更新的(即发生了异构事务),那么复杂度是如何开始的,我们在上面已经谈到过。



一方面,我们仍然可以通过争取基于服务的体系结构来绕过提供分布式事务的需求(我们以事务同质的方式组合服务)。从微服务架构的原理来看,这样的解决方案不是很规范,但是从技术上讲它要简单得多,这就是为什么它经常在实践中使用。另一方面,我们可以离开规范的微服务,但是同时应用一种确保分布式事务的机制:两阶段提交或传奇。本文将探讨第一个选项,并在下一次讨论第二个。



两阶段提交



该机制非常简单:确实有一些事务管理器来协调事务。在第一阶段(准备),事务管理器向资源管理器发出适当的命令,据此,他们将数据写入将要提交的日志中。在收到所有资源管理器关于成功完成第一阶段的确认后,事务管理器开始第二阶段并发出下一个命令(提交),资源管理器将根据该命令应用先前接受的更改。



尽管其表面上很简单,但是该方法具有许多缺点。首先,如果至少一个资源管理器在第二阶段失败,则必须回滚整个事务。因此,违反了微服务架构的原则之一-容错(当我们进入分布式系统时,我们立即认为其中的失败是正常现象,而不是特殊情况)。而且,如果存在很多失败(并且将会有很多失败),那么取消交易的过程将需要自动化(包括编写回滚交易的交易)。其次,事务管理器本身就是单点故障。他应该能够以事务方式向交易发出id-shniks。第三,由于向存储库提供了特殊命令,因此可以合理地假设存储库应该能够执行此操作,就是说,它符合XA标准,但并非所有现代技术都符合它(经纪人(如Kafka,RabbitMQ和NoSQL解决方案,如MongoDB和Cassandra)不支持两阶段提交)。



克里斯·理查德森(Chris Richardson)很好地阐明了从所有这些因素中得出的结论:“ 2PC不是一种选择”(两阶段提交不是一种选择)。



输出量



我们弄清了为什么分布式事务是微服务体系结构的主要技术难题,并讨论了解决此问题的各种方法,并详细讨论了两阶段提交机制。






我邀请所有人注册有关该课程的网络研讨会,在此我将向您详细介绍培训格式,并向所有人介绍该培训计划。






阅读更多:






All Articles