事件溯源:聚合根和性能

Event-Sourcing: Aggregate Roots and Performance

我正在使用事件源构建 Whosebug 克隆。 MVP 很简单:

  1. 用户可以post提问
  2. 用户可以回答问题
  3. 用户可以对非封闭问题的答案投赞成票和反对票

我已将问题建模为聚合根。一个问题可以有零个或多个答案,一个答案可以有零个或多个赞成票和反对票。

但这会导致严重的性能问题。要给答案投票,必须加载问题(作为聚合根),这需要加载其所有答案。在非事件源 DDD 中,我会使用延迟加载来解决这个问题。但是事件源中的延迟加载是非常重要的 (http://docs.geteventstore.com/introduction/event-sourcing-basics/)

将问题建模为聚合根是否正确?

首先不要使用延迟加载(同时使用 ORM)。因此,您可能会发现自己处于更糟糕的境地,而不是等待更长的时间。如果您需要使用它,大多数时候这意味着您的模型完全错误。

您可能需要考虑以下事项:

  1. 你期望这个问题有多少个答案。
  2. 如果有人在您提交答案时发布了答案,会发生什么情况。赞成票也一样。
  3. 赞成票是否只是简单的 +1 而您不再关心它,或者您可以找到用户的所有赞成票,例如将它们更改为反对票(确定赞成票)。

您可能想要单独聚合,不是因为性能问题,而是因为并发问题(问题 2)。

根据性能和您的点赞行为方式,您可能会考虑将其建模为值对象。 (问题 3)

继续read ithttp://dddcommunity.org/library/vernon_2011/

使用 cqrs read/write 分离可能会达到真正的性能提升 http://udidahan.com/2009/12/09/clarified-cqrs/

使用简单的读取模型应该不是问题。对于一个问题,您期望得到最多多少个答案?也许几百对非规范化数据模型来说不是什么大问题。

upvote 事件将由具有少量属性的非常简单的命令触发。

事件处理程序很可能必须加载整个问题。但是通过聚合根 ID 加载这些记录并重放事件非常快。如果每个问题的事件数量非常多(由于答案编辑等),您可以实施快照而不是重放每个事件。该过程是异步完成的,这将使读取模型 "eventually consistent" 具有事件存储。