事件溯源,保持读取端一致

Bog*_*byk 0 event-sourcing

我是 ES 的新手,只是想对脑海中的所有内容进行排序。我听说 ES 实际上正在解决写入和读取数据库之间的一致性问题(肯定会有一些延迟)。但我还是不完全明白怎么办?

如果命令进入域并聚合根触发事件以更新事件存储,则将相同的事件发送到更新读取端??但是如果消息丢失了,我们就会有过时的读取端。

projections唯一的解决方案吗?所以不是从事件更新,而是通过事件存储读取并复制聚合(从开始或从某个快照)。但在这种情况下,它可能违反了一些规则,因为读取端应该很简单,而且它不应该知道域。而且通常读取端是一个单独的应用程序,因此她无法了解聚合。

当然我们也可以使用rabbitMQ或其他一些消息代理来不丢失消息,实际上我认为我们需要。但我也读过,以使其保持一致“你可以使用兔子或 ES”,但是 ES 如何让它自己保持一致?

Ale*_*rev 7

Benjamin 关于事件溯源的目的是完全正确的。

我的回答旨在添加更多细节。

第一的:

读取模型和投影不应该代表聚合状态。

投影是事件源系统为 CQRS 构建读取模型的方式。CQRS 本质上假定写入和读取模型通常用于不同的目的,因此在读取端使用另一个模型是完全有意义的。

因此,您经常会发现多个投影构建了不同的、用途狭窄的模型,针对查询的特定需求。

第二:

“解决一致性问题”可能是指在事件源系统中,每个状态转换都表示为一个事件(或多个事件)。因此,写入始终是事务性的。您选择作为事件存储的数据库应该支持(可以使用一些库或其他工具)实时订阅,这将允许您在投影中按顺序接收新事件。对于新的预测,它将从头开始读取并最终实时读取。订阅通常需要在全局事件流中保持当前处理位置,因此当投影重新启动时,它会从它最后知道的点开始接收事件。

通过这样做,您将保证写入模型中的每个状态转换都将反映在读取模型中。这可能就是您在原始问题中的意思。

第三:

现在,以上所有这些都意味着您不能使用消息总线(仅)将事件传递给投影。经纪人不提供排序保证,并且可以多次传递一条消息。此外,消息代理不会保留历史记录,因此您无法随意构建新的预测。

但是,这并不意味着您根本不能使用代理。有些投影不需要排序并且是幂等的。但是通过代理发布的事件的订阅源是相同的订阅,因此您可以获得有保证的交付,并且可以在必要时读取过去的事件。

第四:

CQRS 并不意味着单独的数据库。有时,使用 CQRS 只是意味着您为域对象使用了一些持久层,因此您可以读写聚合。但是对于查询,您只需随意查询即可。数据库视图是 CQRS 的技术示例。

差不多好了:

预测需要几乎没有逻辑,这是真的。这里的要点是尽可能确保幂等性,因此投影通常不应该使用操作来根据旧值和事件信息计算新值。

但是预测会了解您的领域。您系统中的所有内容都应该了解您的域。

最后:

您绝对可以将不同的数据库用于写入和读取模型,而无需使用事件溯源。您只需要选择一个支持更改提要的数据库。SQL Server、Postgres、CosmosDb 等数据库都有这样的功能。

PS 我建议花一些时间研究这些概念。我可以指向图书存储库,它有 CQRS 和事件溯源示例:https : //github.com/PacktPublishing/Hands-On-Domain-Driven-Design-with-.NET-Core