【问题标题】:Event sourcing pattern: why mustn't I store current state?事件溯源模式:为什么我不能存储当前状态?
【发布时间】:2017-01-20 19:53:41
【问题描述】:

我正在学习事件溯源模式,我无法理解其中的一件事。

在许多教程中都有将实体的当前状态存储在 DB 中的说明。开发人员应该构建一个基础架构,用于从与所需实体相关的数据库中提取所有事件(“事件流”),然后将它们应用于新的所需类型对象,因此最终是当前状态。

让它成为一个银行帐户。要向我的客户返回她当前的帐户状态,我必须:

  1. 提取所有相关事件(DB 中可能有数千个事件)
  2. 计算当时的免费金额。

但是性能呢?我认为最好只存储每个帐户的当前状态,一个新事件会立即对其产生副作用。我说的不对吗?

【问题讨论】:

  • 这就是事件溯源的重点,您可以从事件中重建状态。如果你不这样做 - 你就没有事件溯源。您可能有审核日志或其他内容。所以很难理解这个问题是关于什么的。
  • @Alexey Zimarev 我询问了如何解决事件溯源模式中的性能问题。我认为我的问题并不难理解。
  • 您是否遇到过任何性能问题?

标签: design-patterns repository-pattern event-sourcing


【解决方案1】:

事件溯源的重点是将状态保持为一系列变化,因此拥有当前状态与 ES 相反。

话虽如此,由于性能要求,有时会创建snapshot,这样更新不会从一开始就应用,而只是从快照开始应用。事件存储是针对使用事件溯源的应用程序的专用数据库,它们可以提供快照功能out of the box

等式的另一部分是 ES 是对分隔读写模型的CQRS - Command Query Responsibility Segregation 模式的补充(之前的链接不太正确,IMO,您可能想查看this one)。然后正在执行的命令或领域事件用于不断更新读取模型,这实际上是当前状态的非规范化表示。因此,对于命令,您将从事件 (ES) 构建域对象并对其进行操作,而对于查询,您将绕过事件存储并直接从读取模型中检索数据,该模型可以是关系数据库、文档数据库或其他经过优化的东西适合您的阅读场景。

如果你的应用程序主要是阅读,那么使用 ES 实现的命令端的性能可能不是那么重要。

ES 的好处超出了这个问题的范围,您可以在互联网上找到很多信息(尤其是 Greg Young 和 Udi Dahan)。我个人对此持怀疑态度,并认为如果处理长期运行的业务场景,它是有意义的。

【讨论】:

  • 感谢您的回答和链接,Zdeslav。在我的项目中,我应该构建基础设施来跟踪与某个实体对象相关的所有更改。我认为对于我的场景,将“事件”(作为日志记录)存储在 DB 中比实现清晰的 ES+CQRS 模式更好。
  • 大约 6 到 7 年前,我正在从事一个不使用 ES/CQRS 而是使用“普通”域模型的项目。由于 NHibernate 用于 ORM,我可以使用 interceptors - 在每个模型更新/保存/删除时,我都会获得修改字段的列表,并存储字段名称和值以及发起操作的用户的用户名。只需几行代码即可完成审计跟踪。
猜你喜欢
  • 1970-01-01
  • 2018-01-12
  • 1970-01-01
  • 2017-07-22
  • 2021-02-04
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 2021-10-01
相关资源
最近更新 更多