CQRS 和事件溯源的区别断续器事件溯源CQRS + 事件溯源

CQRS(命令查询责任分离)和事件溯源之间有什么区别?

我相信事件溯源是一种 CQRS。它们之间的区别是什么,事件溯源与其他类型的 CQRS 有何不同?

谢谢


答案 1

断续器

CQRS由Greg Young介绍;他在2010年的解释

CQRS 只是创建两个对象,而以前只有一个对象。分离是根据方法是命令还是查询(与 Meyer 在命令和查询分离中使用的定义相同,命令是任何改变状态的方法,查询是返回值的任何方法)。

通常,这意味着每个对象将使用不同的数据表示形式,以便适合目的。这里的通用语言是指“写入模型”和“读取模型”。通常情况下,将首先对写入模型进行更改,然后异步传播到读取模型。

碰巧的是,数字“2”没有什么神奇之处;您可以轻松地拥有3种不同的表示形式,就像两个一样。

这里的主要好处是,您可以独立地为读取用例和写入用例调整数据结构。

事件溯源

事件溯源用于以非破坏性方式记录状态的模式。状态的每次更改都会追加到日志中。由于这些更改是非破坏性的,因此我们保留在对象生命周期的任何时候回答有关对象状态的查询的能力。

事件的使用可以更有效地利用存储空间(相对于在每次更改后存储状态的完整表示形式),同时保留更改的语义意图(相对于仅存储差异)

Greg 以这种方式描述事件溯源

将当前状态存储为一系列事件,并通过重播该系列事件在系统中重建状态

CQRS + 事件溯源

这些技术经常配对在一起,因为日志作为一种概念数据结构,在支持查询方面并不是特别有效。您通常希望将日志压缩为更适合读取的其他表示形式(可能比写入频率高得多)。

因此,在 CQRS 模式中,我们通常使用日志作为持久性模型,然后从该日志创建对象的合适表示形式的查询,并缓存这些表示形式,以便可以快速支持查询(接受查询中使用的表示形式并不总是反映绝对最新可用信息的折衷方案)。


答案 2

让我们举一个简单的现实世界的例子:

CQRS:我们将使用 cache/redis/elasticsearch 进行读取查询,使用 database/mysql/mongo 进行写入查询。这正是CQRS。分离读取和写入逻辑是 CQRS。

事件溯源:我们使用的所有发布/订阅模式都将属于事件溯源。在这里,我们将消息作为一个事件发布到 queue(kafka/RabbitMQ),订阅者将通过订阅这些队列来简单地使用这些消息。

CQRS + 事件源:让我们仅以上面的例子为例。当写入模型(database/mysql/mongo)出现任何更新时,我们应该如何更新读取模型(cache/redis/elasticsearch)?

我们可以在此处使用事件源。当任何更新进入数据库时,将创建一个事件(包含更改)并将该事件推送到队列。现在,Reader Model(elasticsearch)将订阅这些队列,并在其状态之上应用事件。因此,我们在读取和写入模型中保持相同的状态。


推荐