DynamoDB的事件源,并且恰好在交付后,我应该按AggregateId排序吗?

问题描述 投票:0回答:1

嗨,大数据朋友!

我正在计划使用DynamoDB和Elixir为内部简单消息传递系统实现事件源模型。 DynamoDB中此特定表的目的是记录消息事件的有意义的历史记录(有效负载将存储在其他位置)。

这是我最初的方法...

Domain/TeamId: Primary partition key, splits events by domain (different teams .etc.). This will avoid creating too many partitions.
EventId: Snowflake (RangeKey)
Timestamp: SomeTimestamp
ProfileId: String
MessageId: String
Type: String
AggregateId: String (LSI)

EventId将代表版本,而AggregateId将首先使用profileId_<a_profile_id>_messageId_<a_message_id>代表每个配置文件的消息汇总。我将向表发送事件,例如读取还是删除消息。然后,我将使用==语义将aggregateId用​​作范围键,以聚合所有事件。这是为了支持每种配置文件的消息运行历史。

我能想到的唯一副作用是,查询特定聚合时将无法保证事件的顺序。但是,如果聚合是所有事件的减少,这really有关系吗?

使用此功能,我计划通过检查eventId是否已针对特定团队进行了更新,以及是否再次检查了聚合以确保我们不添加两个MessageRead事件(只想跟踪消息是否已被读取一次以及何时被读取)。如果某种多余的事件最终以某种方式结束,我将在聚合模型上进行处理。

我可以澄清这是否是可以接受的方法?很难找到确切的标题,因为这是一个相对细微而复杂的问题。 Elixir不能完全适合于完美的CQRS实现,但我想确保捕获足够的数据以实现针对我们的用例进行分区的规范事件源模型。

  • 请注意,我无法控制数据库技术或语言!
  • 由于这种限制,聚合键的想法只是为了使查询更少的数据更容易,但是如果aggregateId不是分区键,我就不得不牺牲排序顺序,因为没有什么可改变的范围,这让我很怀疑!
database amazon-dynamodb cqrs event-sourcing dynamodb-queries
1个回答
0
投票

此回复晚了1.5年。希望您喜欢成功的系统,但我会将此答案发布给以后的搜索者。

首先,关于TeamId或域的命名。对于这个名称,我会尽可能地通用。成功的事件来源系统将用于以前从未考虑过的案例。这就是为什么大多数事件源安装都将此字段命名为“ StreamId”的原因。我会这样称呼它。

对流(或您的域)而言,单调增加ID或版本对于事件的所有使用者都很重要。如果您有多个事件流作者,那么这将变得很困难。雪花可以生成单调递增的ID,但只能在单个进程上生成。因此,如果要单调性,则需要某种共识。

因此,我打算通过检查是否已为特定团队更新了eventId,并再次检查汇总以确保我们没有添加两个MessageRead事件(我们只想跟踪消息是否具有被读取一次以及何时被读取)。

非常好。大概是在dynamo中使用条件写入来达到这种效果。如果是这样,那么您已经实现了将这些EventId值设置为所需内容所需的所有一致性。我认为您最好将ID设置为对于特定Stream的每个新记录正好增加1。

由于两个原因,一个流的正好为1的增量很重要:

  1. 顺序可能很重要。并非适用于所有情况,但适用于大多数情况应用程序中,您确实需要按顺序处理事件。如果你是计数或执行其他交换操作,则可能不。但是,大多数业务应用程序无法以与订单无关的操作。同样,如果您正在经历建立该系统的麻烦,您不妨采取一些简单的操作使它对各种情况有用的步骤。

  2. 丢失的消息指示符。如果您的所有服务/角色仅从发电机表中读取,则此重要性就不那么重要了。但是,如果您的分布式系统具有某种消息传递功能,则每个参与者可以确信他们正在处理所有消息(并且仅处理一次),则可以放心地建立自己的聚合和预测。

© www.soinside.com 2019 - 2024. All rights reserved.