事件溯源和处理数据依赖关系



给定一个 REST API,其中包含以下操作,导致事件发布到 Kafka:

  • 添加类别
  • 更新类别
  • 删除类别
  • AddItem (通过某个标识符指代类别)
  • 更新项
  • 删除项

以及多个用户可以同时使用 REST API 的环境,并且使用者都必须获得相同的事件。使用者可能会离线很长时间(超过一天)。可以添加新的使用者,并删除其他使用者。

问题:

  • 事件排序(仅解决单个主题/分区?
    1. 添加类别之前的添加项,无效的类别引用。
    2. AddCategory 之前的 UpdateItem 以前是有效的引用,现在无效。
    3. 在添加项之前删除类别,类别引用无效。
    4. ....其他并发问题的无限列表。
  • 事件存储快照,用于快速重新同步重新启动的使用者
    1. 是否应该为类别和项目提供一个压缩的日志主题,每个实体都由其标识符键控?
    2. 是否可以以某种方式将整个压缩日志主题标识为偏移量?
    3. 压缩日志主题中是否只有一个条目,并且它的数据包含给定偏移量的所有类别和项目的序列化 blob(需要单个主题/分区)。
    4. 如何处理从重播渲染的实体事件存储到命令/事件的"实时流"的切换?对压缩日志视图中的每个项目中的偏移量进行编码,并将其传递给实时事件日志中的重播?

是否有其他系统更适合此问题?

我会根据我在事件溯源方面的经验给你一个部分答案。

事件排序(仅解决单个主题/分区?

  1. 添加类别之前的添加项,无效的类别引用。

  2. AddCategory 之前的 UpdateItem 以前是有效的引用,现在无效。

  3. 在添加项之前删除类别,类别引用无效。
  4. ....其他并发问题的无限列表。

我知道的所有可扩展事件存储都保证事件仅在分区内排序。在 DDD 术语中,事件存储通过按事件的生成顺序重播事件来确保聚合正确解除冻结。Apache-kafka主题似乎是一个不错的选择。虽然这对于应用程序的写入端来说已经足够了,但读取端更难使用它。更难,但并非不可能。

鉴于事件已经由写入方验证(因为它们代表已经发生的事实),我们可以确定系统中出现的任何不一致都是由于事件顺序错误造成的。此外,鉴于读取端最终与写入端一致,丢失的事件最终将到达我们的读取模型。

所以,第一件事,在你的情况下AddItem before AddCategory, invalid category reference,实际上应该是ItemAdded before CategoryAdded(术语是过去的)。

其次,当ItemAdded到达时,您尝试按 ID 加载类别,如果失败(由于延迟CategoryAdded事件),则可以创建一个 ID等于ItemAdded事件中引用的 ID 的NotYetAvailableCategory,标题为"尚不可用,请稍等几毫秒"。然后,当CategoryAdded事件到达时,您只需更新引用该类别 ID 的所有Items因此,主要思想是创建临时实体,这些实体将在事件最终到达时完成

CategoryRemoved before ItemAdded, category reference invalid的情况下,当ItemAdded事件到达时,您可以检查类别是否已删除(通过ListOfCategoriesThatWereDeleted读取模型),然后在您的Item实体中采取适当的操作 - 这取决于您的业务。

最新更新