Design patterns 活动来源和CQR,我错过了什么?

Design patterns 活动来源和CQR,我错过了什么?,design-patterns,cqrs,event-sourcing,Design Patterns,Cqrs,Event Sourcing,我开始阅读与CQR相结合的事件源模式。 据我所知,CQRS模式是一种将写操作和读操作分开的模式。 事件源是一种模式,其中系统中的所有内容都由触发事件的命令启动。事件源模式需要一个事件总线。 有几件事我没能理解 事件存储包含发生在某个实体上的所有事件。如果我想查询该实体的当前状态,我需要查询该实体发生的所有事件,并重新创建其当前状态。 所有事件历史记录都存在于事件存储中。 为什么我不能有一个负责将每个事件保存到事件数据库的微服务(如果我想记录这些事件以便采取进一步的行动,比如Kafka)和一个单独

我开始阅读与CQR相结合的事件源模式。 据我所知,CQRS模式是一种将写操作和读操作分开的模式。 事件源是一种模式,其中系统中的所有内容都由触发事件的命令启动。事件源模式需要一个事件总线。 有几件事我没能理解

事件存储包含发生在某个实体上的所有事件。如果我想查询该实体的当前状态,我需要查询该实体发生的所有事件,并重新创建其当前状态。
所有事件历史记录都存在于事件存储中。
为什么我不能有一个负责将每个事件保存到事件数据库的微服务(如果我想记录这些事件以便采取进一步的行动,比如Kafka)和一个单独的微服务来更新常规数据库中实体的更改(例如,在MongoDB中对实体文档的简单更新)。当这些微服务完成其工作时,该事件将从事件存储中删除(假设我使用队列实现该事件存储)。 这样,每当我需要查询实体的当前状态时,我只需查询数据库,而不是查询事件存储并重建当前状态(或基于事件存储重新计算状态并定期缓存结果)。我不明白为什么必须永远存储所有事件,为什么不是可选的

例如,接收事件的Lambda函数生成事件,并将它们存储在每个事件类型的单独SQ中。每个SQS都有自己的lambda函数,负责处理相应的事件类型。事件处理后将被删除。

事件源(有或没有CQR)具体指存储实体的状态,通常使用特定于域的事件。当您需要运行需要来自该实体的数据的业务逻辑时,您应该按顺序将事件投影到某个状态并使用该状态

将域事件存储在类似Kafka的东西中是绝对有效的做法,但将实体本身存储在文档或普通表单数据库中(通过投影事件,然后存储该事件或其他任何内容),这不是事件源

我假设你知道活动外包的好处,所以我在这里不赘述,但请随意添加评论,我会详细介绍

为什么不将事件存储在Kafka之类的东西中,并在加载过程中不使用它们呢?如果您没有将快照存储在与事件相同的数据库中,那么您将面临出现并发冲突的真正风险:例如,如果您决定在引发事件时最多使用一次语义,则会引发重复条目、引发冲突事件或丢失事件。这些直接意味着你不能真正依靠你所发出的事件来成为真相的来源

我不明白为什么必须永远存储所有事件,为什么不是可选的

Per(强调矿山)

我们可以查询应用程序的状态以了解世界的当前状态,这回答了许多问题。然而,有时我们不只是想知道我们在哪里,我们还想知道我们是如何到达那里的

这将导致在事件日志之上构建许多设施:

  • 完全重建:我们可以完全放弃应用程序状态并重建它
  • 时态查询:我们可以在任何时间点确定应用程序状态
  • 事件重播:如果过去的事件不正确,我们可以通过反转它来计算后果
无法丢弃事件的原因是事件本身具有值。如果不是这样的话,那么事件源是一个糟糕的选择。事件源模式要求保存所有事件,以便可以重用它们

事件源模式需要一个事件总线

事件源不需要总线,除非您需要将更改(事件)通知其他系统/域

如果我想查询这个实体的当前状态,我需要查询发生在这个实体上的所有事件,并重新创建它的当前状态

嗯,有点。您只需要在处理新命令时执行此操作,并且需要验证应用该命令不会使“实体”(您称之为“实体”)不一致。注意,这涉及CQR的命令端,而不是查询端

对于查询/读取模型方面,您有许多不同的选项。在使用事件源时,通常会有一个单独的数据存储,用于维护事件的非规范化版本以及在事件发生时更新的相关数据。这个单独的商店经常是,这是太多了去为这个答案的目的。您的读取模型也可以是关系数据库、平面文件,或者您可以想到的任何其他存储数据的方式。它的数据通过总线、轮询数据库或其他方式在事件发生时接收事件,从而与写模型保持一致

查询事件流并实时处理(或部分处理)它们以构造查询也是绝对有效的,但需要这样做的情况相对少见

所有事件历史记录都存在于事件存储中。为什么我不能 负责将每个事件保存到 事件数据库(如果我想记录这些事件以便采取进一步行动。 类似卡夫卡)和一个单独的微服务来更新 对常规数据库中实体的更改(对实体的 例如,mongodb中的文档)

你可以

当这些微服务完成其工作时,此事件将被取消 从事件存储中删除(假设我实现了此事件存储 使用