【发布时间】:2021-10-01 12:19:45
【问题描述】:
我对 kafka 和 RocksDB 作为事件存储的事件采购有一些疑问。 我想用 Apache Kafka 实现事件溯源,我想到了这样做:
- 为命令创建一个主题,其中 aggregateID 用作键以确保排序
- 为事件创建一个主题,其中聚合ID 用作键以确保排序。其他服务可以使用此主题来处理这些事件。
- 创建状态存储 (rocksDB) 以持久化事件
坚持事件:
我们可以通过为事件生成一个唯一的 id 来保存事件。此 id 以 aggregateID 为前缀,并与 ULID(通用唯一字典排序标识符)连接,例如customer-123@01FBDJAVZC04GWKGCKE6ZQXY5T 其中 customer-123 是聚合 ID,@ 之后的所有内容都是生成的 ulid(可排序)。 RocksDB 中的所有条目都按其键按字典顺序排序,因此通过生成这样的键,我们可以确保在读回事件以构建聚合状态时排序。同样,我们可以通过在 RocksDB 中进行范围查询来读取给定聚合 ID 的事件,例如 store.range(from, to)。在这种情况下,范围查询将如下所示: store.range("customer-123@", "customer-123@z")。这样,我们将获取从 customer-123 到 customer-123 的最后一个事件的所有事件,因为 z 是字母表中的最后一个。
因此流应用程序将执行以下操作:
-
当一个命令进来时,它会通过使用范围查询(如上所述)从 Rocksdb 中为给定的聚合 id 加载所有事件。
-
如果命令有效,我们会创建一个或多个事件并将其保存到 RocksDB(如上所述),并将这些事件推送到事件主题,以便感兴趣的消费者可以对这些事件做出反应。
所以我的问题是:这是一个好方法吗?将所有事件保存到本地状态存储是否可以?如果我们在加载聚合时进行大量范围查询,rocksDB 会遇到麻烦吗?是的,它将使用大量本地存储,但我们可以通过添加更多分区和节点来扩展它。
谢谢
【问题讨论】:
标签: java apache-kafka apache-kafka-streams event-sourcing rocksdb