我正在寻找一个关于如何选择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持开放的一致性和可用性..但是分区容差部分呢??
我真的迷路了,我需要争论才能做出相应的选择。
答案 0 :(得分:4)
MongoDB
为Event store
CQRS
。它由Event sourcing
+ CRM
基于网络的MongoDB document
应用程序使用。
为了提供100%无交易但类似交易的保证,可以一次性保存多个事件(所有事件或所有事件都没有),我使用events commit
作为nested documents
,并使用事件为MongoDB
。如您所知,version
有working, in production implementation。
对于并发,我使用乐观锁定,为每个Aggregate steam
使用Aggregate stream
属性。由{dublet Aggregate class
x Aggregate ID
标识sequence
。
事件存储还使用commit
在每个commit
上以相对顺序存储提交,在每次提交时递增,使用乐观锁定进行保护。
每个GUID
包含以下内容:
EventWithMetadata
,EventWithMetadata
的列表,每个event class/type
包含MongoDB
,有效负载包含字符串(实际事件的序列化版本)。
aggregateId
集合具有以下索引:
aggregateClass
,version
,unique
为events.eventClass
sequence
,sequence
Aggregate
这些索引用于强制执行常规事件存储规则(没有为aggregateId
的相同版本存储事件)和查询优化(客户端可以选择仅限某些事件 - 按类型 - 来自所有流)。
如果您剥离事件的全局排序(sequence
属性)并将该职责移至event publisher
,则可以按event publisher
使用分片进行缩放,但这会使事情变得复杂event store
需要与Intel I7
保持同步(即使出现故障!)。我建议只在你需要时才这样做。
此实施的基准(8GB
RAM
上的MongoDB
):
我注意到counting
在MongoDB
事件存储中的事件数量很慢。我不知道为什么,但我不在乎,因为我不需要这个功能。
我建议将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函数)