【问题标题】:How can I make projection faster in asp.net core app?如何在 asp.net 核心应用程序中更快地进行投影?
【发布时间】:2021-12-30 19:09:18
【问题描述】:
我有两个数据库的网络应用程序:
- EventStoreDB - 用于事件
- PostgreSQL + Marten - 用于预测
对于订阅并将数据从 eventstore 添加到 postgres,我使用此示例 sample
但是,当我进行创建操作并获得成功结果时,接下来我尝试从 postgres 加载新对象,postgres 没有我的新对象。
如何使“事件从 eventstore 应用到 postgres 更快或同步”?
【问题讨论】:
标签:
asp.net-core
asynchronous
olap
event-sourcing
【解决方案1】:
根据定义,事件源系统在将事件存储在事件存储中与将其投影到读取模型之间存在时间滞后。除非您在将事件提交到存储时将事件同步应用到内存中的读取模型,否则延迟始终存在。但是这种方法会限制您将服务作为单个实例运行,否则,您无法确定内存中的状态是否同步。有一些技术可以解决这个问题,但它们相当复杂。
由于您没有描述需要立即获取读取的模型数据,因此很难给出具体建议,但我有一些提示。
-
如果 UI 需要它,并且 UI 需要新的实体状态,您可以将实体状态作为命令处理结果返回,因为您已经拥有它。然后,UI 可以立即显示状态,而无需执行任何查询。
-
相同的场景,但您将一组新事件返回到 UI。如果 UI 位是用 React 和 Flux 之类的东西构建的,他们很可能已经在那里有了“事件源”(这就是 Flux 本质上的),并通过他们的 reducer 应用这些事件,他们可以在不查询读取模型的情况下更新 UI。
-
如果您知道需要同步的读取模型(我不能说您有多少),您可以将事件提交位置作为元数据属性或仅作为文档属性传播到读取模型。然后,您可以保持 API 调用(基本上是等待),直到读取模型更新位置属性等于或大于提交位置。缺点是您只能针对特定的读取模型执行此操作,因此您的命令处理程序需要对读取端了解太多。
-
与 (3) 类似,但您检查检查点存储位置。如果检查点存储没有通过批处理进行优化,它将很快传递最后一个事件提交位置,然后您将 200 OK 返回给调用者。它比(3)简单一点,因为它只关心订阅检查点,而不是单读模型,但您需要访问检查点存储。
-
UI在他们处理完命令后也可以做同样的事情,你需要返回最后一个事件的提交位置,他们查询等待。
我已经看到上述所有方法都在生产中工作,但我更喜欢的解决方案是 (1) 和 (2)。
要使任何这些工作,您的命令服务需要向调用者(API 或其他)返回一个复杂的结果,就像我 done in Eventuous 一样。