cqrs_CQRS提高一致性

cqrs

我经常听到这种说法。 作为一个强烈鼓励CQRS框架的作者,我显然对这种观点有偏见,并且不赞成这种观点。

当然,声明和我的分歧需要上下文和限定条件。 如果您有传统的整体式系统,其中所有数据操作都在单个数据库上完成,并且该单个数据库支持ACID事务,那么可以,切换到CQRS会降低一致性。 但是,这不是通常出现CQRS的上下文,也不是我建议在其中使用它的上下文。上下文是微服务,越来越多的行业专家建议人们远离整体,转而使用微服务。

微服务降低一致性

微服务的核心原则是它们应该拥有自己的所有数据。 另一个核心原则是他们应该能够自主行动。 这意味着他们无需依赖其他服务(特别是对其他服务的同步调用)即可实现其负责的功能。

如果服务是自治的,则它需要存储其实现其功能所需的所有数据。 有时,这些数据可能由其他服务拥有-因此,为了起作用,这些服务需要发布该数据,以供该服务使用和更新其自己的商店。 这意味着在微服务系统中,相同的数据将被存储在许多地方。 这些数据在整个系统中是否会高度一致? 除非每次执行操作,否则都将停止对整个系统的所有其他请求,并处理该操作直到成功,否则答案是“否”,这通常是不一致的。

因此,从本质上说,切换到微服务就是降低一致性的切换。 一致性降低是微服务的结果。

不一致可能非常严重

因为我们正在使用微服务,所以我们的系统可能会变得不一致,因此我们需要对此进行处理。 我们的系统如何变得不一致取决于我们如何处理它。 处理分布式系统中的不一致性的典型,非常高级的手动波浪方法是使用最终的一致性。 但是,实际上是如何实现的呢?

假设服务B需要一些服务A拥有的数据来实现其职责。 在这种情况下,A负责写入数据,这是处理命令的事情,而B负责读取数据,它负责查询。 为了使B能够自主行动,它不能直接查询A,它需要让A向其推送数据,以便它可以更新自己的查询存储,然后在需要时使用它在本地查询。

服务A可以同步执行此操作,当对服务A执行操作时,它将调用服务B以用结果更新它。 现在,这在纸上可以正常工作,但是当服务B那时关闭时会发生什么呢? 服务A是否必须继续重试,直到服务B重新启动? 如果服务A然后出现故障怎么办?

如您所见,我们现在遇到一个一致性问题,这个问题最终不会变得一致。 服务A已更新,但服务B无法更新。 它会永远保持不一致,我们可以说它最终会不一致,并且需要人工干预才能修复。 出现此问题的原因是,我们在一个操作中将命令责任和查询责任结合在一起,并且由于该操作不是原子操作,因此该操作的部分失败将导致终端不一致。

CQRS使您保持一致性

CQRS意味着将命令职责与查询职责分开。 在我们的方案中,使用CQRS,服务A处理该命令,并更新其状态并完成。 然后,在一个单独的操作中,另一个进程将对A执行该操作的结果,并将其异步推送到服务B。

由于该操作是异步的,因此服务B无需在此时启动-例如,它可以使用至少一次消息队列来处理消息。 如果服务B当时没有启动,则系统将在一段时间内不一致。 但是,当服务B重新启动,然后处理该消息时,系统将再次变得一致,最终将保持一致。

因此,通过使用CQRS,我们可以取回在迁移到微服务时丢失的一些一致性保证。 我们没有全球一致的系统,但是我们可以保证最终的一致系统。

CQRS是必不可少的罪恶

CQRS非常复杂,远比在高度一致的数据库上通过一次操作处理数据的命令和查询责任复杂得多。 但是,在微服务世界中,我们无法依靠单个高度一致的数据库。 在那个世界里,矛盾是必然的。 如果有人说在微服务中使用CQRS意味着您失去了一致性–他们没有意识到在开始使用微服务时就失去了一致性,那么并不是CQRS失去了这种一致性。 相反,CQRS是一个非常强大的工具,它使我们能够解决微服务的内在矛盾,从而为我们提供最终的一致性,而不是终端的不一致。

翻译自: https://www.javacodegeeks.com/2016/11/cqrs-increases-consistency.html

cqrs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值