CQRS如何为更具伸缩性的应用程序做出贡献

时间:2014-06-10 07:46:22

标签: domain-driven-design cqrs

最近我在CQRS架构上阅读了很多内容。关于为什么应该使用CQRS的最重要的一点是可扩展性。

现在我不太明白这是如何运作的。

假设您拥有typical CQRS应用程序设计。

  • 两个数据存储
  • 一个用于指挥面
  • 一个用于查询面
  • 处理Command时会发送一个可以更新第二个数据存储的事件

经常声明,拥有一个用于查询的数据存储区和一个用于处理命令的数据存储区将使您的应用程序更具可伸缩性。 但是,如果存储事件数据的第二个数据存储需要响应查询请求并且还需要根据传入的事件不断更新自身,那么它如何工作呢?

为什么没有一个存储命令的数据存储区以及查询方可以重新使用存储的数据来获取结果数据?

2 个答案:

答案 0 :(得分:11)

您可能会感到有趣的是从old blog post本人那里阅读Greg Young,他在那里解释了CQRS到底是​​什么。

CQRS不是关于拥有2家不同的商店,而是如Greg的文章所述:

  

CQRS只是创建了之前的两个对象   只有一个。基于方法是否为a来进行分离   命令或查询

您在此处描述的更多是事件采购。

现在回到你的问题:How can CQRS contribute to more scalable applications? 格雷格也回答了这个问题:

  

CQRS允许以不同方式托管两种服务,例如:我们可以托管   在25台服务器上读取服务,在两台服务器上读取服务。该   处理命令和查询从根本上说是不对称的   对称地缩放服务并没有多大意义。

那就是它!

答案 1 :(得分:3)

Two Datastores
One for the Command Side
One for Query Side
When a Command has been processed an Event is send which could update the second Datastore

这是CQS与ES(事件采购),不要混淆事情!

事件源是关于存储通过处理传入命令引发的域事件。因此,您可以随时播放它们。这使得读取方面更加灵活,因为您可以随时更改读取数据库结构,之后您只需重放域事件而不是编写一些花哨的迁移代码。存储命令不合适,因为您不一定拥有相同的环境(例如服务器上的时间不同),因此您无法安全地重放它们。命令存储仅用于记录目的......

命令和查询责任隔离是指将传入请求分为两组:写(命令)和读(查询)。这背后的基本思想是,您不必通过编写它来阅读您的关系数据库来使用相同的ORM实体。因此,您可以通过读取来保留对象关系映射,从而使事情变得更快。后来它进行了改进,现在它意味着您可以通过读取部分使用多个数据库,每个数据库都特定于一组查询。例如,如果图形数据库(如neo4j)更适合某些查询,则添加neo4j数据库而不是使用相同的关系数据库来提供这些查询。这可以让事情变得更快......