use*_*251 12 nosql cqrs event-sourcing event-store
我正在进行一个新项目的研究阶段,目前我正与一位工作同事就该项目的架构进行辩论.
我们已经同意我们将使用CQRS和使用azure的事件源来创建分布式消息传递系统.它将是一个SPA,前端使用角度js,后端将是Web API.
我们现在讨论了如何设置数据库,这就是发生差异的地方.
我们同意将数据库拆分为两个数据库,一个用于读写.我的同事想要将sql server用于读写数据库,因为他在sql中度过了他的整个职业生涯并且除了sql之外不想听到任何其他内容.另一方面,我一直在研究NoSql,我觉得它适合读取数据库,因为它更适合性能.
由于CQRS完全是关于最终的一致性,我已经读过NoSql数据库也基于此,现在让我考虑将NoSql用于写入数据库.
我们还计划为每个聚合根创建一个事件表,而不是一个包含所有事件的通用事件表.由于这些表不是关系型的,因此我想到为什么我们应该使用sql server.
我的问题更多的是人们如何创建活动商店的最佳实践或一般方法.
Ale*_*ger 11
注意:我的答案来自2014年.时代已经发生变化,现在有几个NoSQL数据库支持多文档事务.我仍然提倡使用PostgreSQL来存储事件,因为它有很棒的JSON支持.
最后一个问题主要是基于意见的,所以让我从我的角度回答前两个问题.
在此之前,让我说我们正在为我们的事件存储使用SQL服务器(Postgres).使用CQRS + ES,只需要一个主数据库来写入数据库,从存储库中读取存储库(不要与CQRS读取混淆).在这种设置中,可扩展性应该不是问题(如果Reddit可以在主/ 从中与Postgres一起扩展,那么你也可以).
我已经对NoSQL商店的各种选项进行了广泛的评估.在一天结束时,对于CQRS + ES设置,我发现在主/从模式下的SQL方法没有任何优势,IMO将超过使用NoSQL数据库所带来的缺点.
特别是,在SQL存储中实现乐观锁定(对streamId和version字段的唯一约束)是微不足道的,但是在简单的NoSQL键值存储中实现可靠的乐观锁定是非常困难的(不可能的?).
对于一些文档存储,它是可能的(我认为有一个原因,为什么NEventStore只支持RavenDB和MongoDB.):
在Postgres中,我正在为所有事件使用一个事件表.
至于第二个问题,我认为你必须区分事件存储和读取模型.我们正在为事件存储使用SQL服务器(出于上述原因),但对于CQRS 读取模型,我认为NoSQL"数据库"非常适合,因为最终的一致性方法非常适合NoSQL范例.此外,人们通常只能通过密钥查询读取方,因此您可以使用任何您喜欢的键值存储并满足您的需求.我们甚至根本不使用数据库,而是根据需要重新构建的内存网格.
就个人而言,我更喜欢每桌一个聚合,但这取决于具体情况.即使对所有聚合使用一个表,也可以使用分区技术来缓解潜在的性能问题.
我认为NoSQL对于读写端都是可行的,但SQL数据库确实提供了一个实用的特性:事务性.当您需要在一个事务中提交多个事件时,这尤其有用.对于NoSQL数据库,您可能必须更改架构才能实现此目的.例如,在采用Mongo时使用每个文档的每个事务.或者你可以使用Cassandra并将每一行作为聚合(每列一个事件,Cassandra为行级提供部分事务性).
但是,如果您的程序每个事务只发布一个事件或者一致性不是强烈要求,那么这不是一个很大的优势.