选择NoSQL数据库在CQRS设计的应用程序中存储事件

时间:2017-04-14 09:11:26

标签: domain-driven-design cqrs consistency nosql

我正在寻找一个关于如何选择NoSQL数据库引擎以便在CQRS设计的应用程序中存储所有事件的良好,最新和“决策帮助”解释。

我目前是NoSQL所有事物的新手(但是学习):请明确并且毫不犹豫地以(几乎太多)精确的方式解释你的观点。这篇文章可能值得像我这样的其他新人。

此数据库将:

  • 能够在前视图询问的每个更新中插入2到10行(在我的情况下,更新频繁)。想想每分钟有数千个更新,它会如何扩展?

  • 非常需要一致且安全失败,因为事件是应用程序真相的来源

  • 实体之间不需要任何链接(比如RDBMS),除了用户ID / GUID(我不知道它是否关键或需要)

  • 接收包含3到10个“列”的事件(序列ID,事件名称,日期时间,JSON /二进制编码参数包,一些上下文信息......)。如果没有在面向列的数据库类型中定位您的观点,如果它符合所有其他要求,它可能是面向文档的

  • 用作队列或从外部AMQP系统发送/读取,如RabbitMQ或ZeroMQ(如果您还可以参数/解释那么,还没有使用那部分),因为视图投影将被构建事件

  • 需要通过序列ID进行某种过滤,例如SELECT * FROM events WHERE sequence_id > last_sequence_id,以便订阅者(或队列系统)能够从给定点进行同步

我听说过用于CQRS事件存储的HBase,但MongoDB可能适合吗?甚至Elasticsearch(不会打赌那个......)?我也对RDBMS持开放的一致性和可用性..但是分区容差部分呢??

我真的迷路了,我需要争论才能做出相应的选择。

3 个答案:

答案 0 :(得分:4)

MongoDBEvent store CQRS。它由Event sourcing + CRM基于网络的MongoDB document应用程序使用。

为了提供100%无交易但类似交易的保证,可以一次性保存多个事件(所有事件或所有事件都没有),我使用events commit作为nested documents,并使用事件为MongoDB。如您所知,versionworking, in production implementation

对于并发,我使用乐观锁定,为每个Aggregate steam使用Aggregate stream属性。由{dublet Aggregate class x Aggregate ID标识sequence

事件存储还使用commit在每个commit上以相对顺序存储提交,在每次提交时递增,使用乐观锁定进行保护。

每个GUID包含以下内容:

  • aggregateId:string,可能是EventWithMetadata
  • aggregateClass:string,
  • version:integer,对于每个aggregateId x aggregateClass,
  • 递增
  • 序列,整数,每次提交递增,
  • createdAt:UTCDateTime,
  • authenticatedUserId:string或null,
  • 事件:EventWithMetadata的列表,

每个event class/type包含MongoDB,有效负载包含字符串(实际事件的序列化版本)。

aggregateId集合具有以下索引:

  • aggregateClassversionuniqueevents.eventClass
  • sequencesequence
  • Aggregate
  • 查询优化的其他索引

这些索引用于强制执行常规事件存储规则(没有为aggregateId的相同版本存储事件)和查询优化(客户端可以选择仅限某些事件 - 按类型 - 来自所有流)。

如果您剥离事件的全局排序(sequence属性)并将该职责移至event publisher,则可以按event publisher使用分片进行缩放,但这会使事情变得复杂event store需要与Intel I7保持同步(即使出现故障!)。我建议只在你需要时才这样做。

此实施的基准8GB RAM上的MongoDB):

  • 总聚合写入时间为:7.99,速度:每秒写入12516个事件
  • 总聚合读取时间为:1.43,速度:每秒读取35036个事件
  • 总读取模型读取时间为:3.26,速度:每秒读取30679个事件

我注意到countingMongoDB事件存储中的事件数量很慢。我不知道为什么,但我不在乎,因为我不需要这个功能。

我建议将event store用作{{1}}。

答案 1 :(得分:2)

https://geteventstore.com/是专为事件流设计的数据库。

他们非常认真地对待事实来源(你的事件)的一致性和可靠性,我自己用它来每秒读/写成千上万的事件。

答案 2 :(得分:0)

我有一个.NET Core事件源实施项目https://github.com/jacqueskang/EventSourcing

我从使用实体框架核心的关系数据库(SQL Server和MySQL)开始。 然后转移到AWS,所以我编写了DynamoDB扩展。

我的经验是,关系数据库可以完美地完成这项工作,但这取决于需求和您的技术堆栈。如果您的项目是基于云的,那么最好的选择可能是云提供商的无SQL数据库,例如AWS DynamoDB或Azure CosmosDB,它们具有强大的性能并提供其他功能(例如DynamoDB可以触发通知或lambda函数)