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

4

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

  • AddCategory(添加类别)
  • UpdateCategory(更新类别)
  • RemoveCategory(删除类别)
  • AddItem(通过某个标识符引用类别)
  • UpdateItem(更新条目)
  • RemoveItem(删除条目)

同时,存在多个用户可能同时使用REST API的环境,并且消费者必须获取相同的事件。消费者可能离线一段时间(超过一天)。可以添加新的消费者,也可以删除其他消费者。

问题:

  • 事件排序(只能使用单个主题/分区解决?)
    1. 在AddCategory之前执行AddItem,类别引用无效。
    2. 在AddCategory之前执行UpdateItem,曾经是有效引用,现在无效。
    3. 在AddItem之前执行RemoveCategory,类别引用无效。
    4. ...无限的并发问题清单。
  • 事件存储快照以便重新启动消费者时进行快速重新同步
    1. 是否应该为类别和条目都创建压缩日志主题,每个实体都以其标识符为键?
    2. 整个压缩日志主题是否可以被识别为一个偏移量?
    3. 压缩日志主题中应该只有一个条目,其数据包含给定偏移量下的所有类别和条目的序列化blob(这将需要单个主题/分区)。
    4. 如何处理从重放渲染实体事件存储到“实时流”命令/事件的交接?在压缩日志视图中为每个条目编码偏移量,并将其传递给从实时事件日志重新播放?

是否有其他系统更适合解决这个问题?

1个回答

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

事件排序(只能绕过单个主题/分区?)

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

  2. 在添加类别之前更新项目,曾经是有效引用,现在无效。

  3. 在添加项目之前删除类别,类别引用无效。
  4. ....其他并发问题的无限列表。
我所知道的所有可扩展的事件存储都仅保证分区内的事件排序。在DDD术语中,事件存储确保通过按照生成顺序重放事件来正确地重新构建聚合。Apache-kafka主题似乎是一个不错的选择。虽然这对于应用程序的写入端来说已经足够了,但对于读取端来说则更加困难。更加困难但不是不可能。
考虑到事件已经由写入端验证(因为它们代表已经发生的事实),我们可以确定系统中出现的任何不一致都是由于事件的错误排序引起的。此外,鉴于读取端与写入端是最终一致的,缺失的事件最终将到达我们的读取模型。
所以,首先,在你的情况下,“AddItem before AddCategory, invalid category reference”实际上应该是“ItemAdded before CategoryAdded”(术语在过去时)。第二,在“ItemAdded”到达时,您尝试按ID加载类别,如果失败(由于延迟的“CategoryAdded”事件),则可以创建一个“NotYetAvailableCategory”,其ID等于“ItemAdded”事件中引用的ID,并且标题为“Not Yet Available Please Wait a few miliseconds”。然后,当“CategoryAdded”事件到达时,您只需更新所有引用该类别ID的“Items”。因此,主要思想是创建临时实体,这些实体将在它们的事件最终到达时完成。在“CategoryRemoved before ItemAdded, category reference invalid”的情况下,当“ItemAdded”事件到达时,您可以检查该类别是否已被删除(通过具有“ListOfCategoriesThatWereDeleted”读取模型),然后在您的“Item”实体中采取适当的操作-这取决于您的业务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接