当前位置: 首页 > 知识库问答 >
问题:

在事件存储区中保存每个聚合的最新版本的快照

鲁文昌
2023-03-14

我们目前使用SQL支持的事件存储(典型的2表实现),团队中的一些人担心,即使我们只使用事件存储进行写操作,事情可能会变得有点慢,因此建议不要到处添加快照,而是实际保持每个聚合的最新状态(以JSON格式)完全一致(与事件流)的快照。系统上的所有查询最终都将在读端完成,典型的SQL数据库将从ES(写)端以最终一致性的方式更新。

拥有这样一个系统将允许我们享受拥有事件存储的好处,同时完全消除任何可能的性能问题。我们目前没有使用任何“时间旅行”功能,尽管迟早会这样。

这是个好办法吗?里面有些东西让我不舒服。例如,如果我们需要某种时间旅行特性,在每个聚合的事件流中没有快照将证明是性能灾难。当然,我们可以拥有每个聚合实例的最新快照,也可以拥有整个事件流的快照。

如果我们决定走这条路,我们应该将给定聚合的快照更新事务化到同一聚合上的事件更新,还是应该只更新事件并以最终一致的方式更新快照?

共有1个答案

戎兴言
2023-03-14

在给系统添加不必要的复杂性之前,您可能应该运行自己的基准测试。我们已经注意到,当需要查询和应用数千个事件来从事件流重建聚合时,会出现一些性能问题,其中JSON到对象的反序列化是最大的性能瓶颈。如果您的每个聚合只有很少的事件(例如,<100),您可能不会注意到实践中的任何显著差异。

大多数事件存储区记录每n事件/提交一次快照,例如每50-100次事件,并在程序集上查询最新的快照并应用自上次快照以来丢失的事件。如果还将所有旧快照保存在快照数据库中,时间旅行特性将与通常的查询一样快,并且只需要稍微多一点的持久性空间,而这在现在是便宜的。

应该始终从原始事务中写入快照(并且可以在另一个线程中生成),因为如果缺少最后一个快照,这并不重要,但是您不希望您的业务事务由于快照写入事务中的错误而失败。

根据您通常的系统正常运行时间和数据大小,将快照保存在内存或分布式缓存/graid或其他数据库(非SQL)中可能是有意义的。

 类似资料:
  • 如何读取自创建以来该聚合的所有事件?

  • 我有一个像下面这样的用例。对于每个传入的事件,我希望查看某个字段,看看它的状态是否从a变为B,如果是,则将其发送到输出主题。流程是这样的:一个带有键“xyz”的事件以状态A进入,一段时间后另一个带有键“xyz”的事件以状态B进入。 有没有更好的方法使用DSL来编写这个逻辑? 上面代码中关于聚合创建的状态存储的两个问题。 null 提前道谢!

  • 问题内容: 我有一些产品数据需要在Redis缓存中存储多个版本。数据是JSON序列化的。获取纯(基本)数据的过程非常昂贵,将其自定义为不同版本的过程也很昂贵,因此我想缓存所有版本以尽可能进行优化。假设自定义基于单个参数,我可以将该参数用作缓存键的一部分。 我计划用来检索产品数据的过程是这样的: 一切都很好,但是我现在正在尝试找出在基础数据源发生更改时使缓存数据无效的最佳方法。如果基本产品信息发生变

  • 我有一些需要在Redis缓存中存储多个版本的产品数据。数据是JSON序列化的。获取普通(基本)数据的过程是昂贵的,将其定制成不同版本的过程也是昂贵的,因此我希望缓存所有版本以尽可能优化。假设定制是基于一个参数的,我可以使用该参数作为缓存键的一部分。 我计划用于检索产品数据的过程如下所示: 所有这些工作都很好,但我现在正在尝试找出当底层数据源更改时使缓存数据无效的最佳方法。如果基本产品信息发生变化,

  • 也许这听起来像是个愚蠢的问题,但我被困住了。我有ant build.xml,它有maven-ant-tasks 我需要提供最新版本,因为它是我自己的工件,似乎ant maven任务不知道解决它。我得到的错误 生成失败.../BUILD.xml:20:无法解析项目:缺少:----------------请尝试从项目网站手动下载文件。 然后,使用命令mvn install:install-file-d