浅谈CQRS

Posted 攻城狮白玉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈CQRS相关的知识,希望对你有一定的参考价值。

目录

一、什么是CQRS

二、为什么要用CQRS

三、CQRS的使用

四、CQRS的好处

五、CQRS的缺点

六、何时使用CQRS

总结


一、什么是CQRS

Greg Young 在 2010 年创造了CQRS(Command Query Responsibility Segregation)架构模式。

CQRS是基于CQS,CQS (命令查询分离)设计模式建议将对象的方法映射到两类:方法要么改变对象的内部状态,但不返回任何内容,要么只返回元数据。这种方法称为Command。或者一个方法返回信息但不改变内部状态。这种方法称为Query。

命令查询职责分离(Command Query Responsibility Segregation,CQRS),是一种读写分离模式,旨在从业务上分离命令(Command,也就是写操作)和查询(Query,读操作)的行为。从而使得逻辑更加清晰,便于开发人员对不同部分进行针对性的优化。

由CQS演变而来的CQRS 的核心思想是将这两类不同的操作进行分离,然后在两个独立的service中实现。这里的service一般是指两个独立部署的应用。在某些特殊情况下,也可以部署在同一个应用内的不同接口上。

二、为什么要用CQRS

传统的开发方式,就是读写都是用的同一个模型。如下图所示,请求和返回都是DTO。一个DTO模型就表达了用户所有的CURD的意图了。而且为了适应同时适应查询和创建操作,DTO被设计的面面俱到,也就显得臃肿。从而在传输中存在不必要的字段传递。

 有的同学就会问了,那我数据库不也有读写分离吗,你这CQRS不会是新瓶装老酒,拿个新名词来忽悠人的吧。且慢,容我慢慢道来。如果是在传统的开发方式,就算你是数据库读写分离了,你用的数据模型还是同一个,如下图所示。而且每次操作,在DTO与领域对象间进行多次转换,增加了系统复杂度。即使你数据库读写分离了,但是读写模型没有拆分的话,服务的并发瓶颈还是在那里。

在实际应用场景中,读取和写入工作负荷通常是非对称的,具有截然不同的性能和缩放要求。正常都是读多写少,同时读取的接口有各式各样的参数回显需求。而写入的话,一般的数据都是比较固定的。同时数据查询都不会改变数据库的数据。传统开发方式的读写操作围绕同一数据模型展开,对于读多写少的系统而言效率并不是最高的,特别在读操作为主的高并发系统中缺点就尤为突出。

三、CQRS的使用

鉴于传统开发模式的高并发短板,因此,我们把读写模型进行拆分。CQRS根据读写职责的不同,将读取和写入分离到不同的模型,使用命令来更新数据,使用查询来读取数据。这时的模型如下图所示。我们的command model对应到写数据库,query model对应到了读数据库。此时,数据库的读写分离。

红色线部分就是Command端,其对应的是Command Model对其发送Command操作的指令向写数据库中写入数据。

绿色线部分是Query端作为查询操作,通过Query Model向读数据库获取数据,通过蓝色向左的线逐层把数据返回结果给Client

四、CQRS的好处

  • CQRS的好处,读写分离,解决的就是复杂软件系统中的读多写少的问题。
  • 因为读和写的参数不一样,因此要分别定义写接口的参数,和读接口的参数。
  • 写接口一般比较少变动,可以遵守范式来写。
  • 读接口根据业务相对会变动比较多,而且有时候需要直接跨层调用,如从Application层直接调用Infrastructure层。
  • CQRS很适合基于事件的编程模型。CQRS系统被分割成独立的服务,与事件协作进行通信。这使得这些服务可以轻松地利用事件溯源(Event Sourcing)的优势。

五、CQRS的缺点

凡事有利必有弊,使用CQRS,由于读写的模型分离了,首先从代码量上面肯定增加了,更重要的一点便是增加了软件系统的复杂。

CQRS也算是一种开发模式,一种新思想的引入也提高了程序员的开发门槛。

六、何时使用CQRS

以下情况建议使用CQRS模式:

  • 首先便是正文中提到的读多写少的场景。这个时候可以考虑使用CQRS。
  • 读写性能分别的要求,数据读取性能必须独立于数据写入性能进行优化的场景。可以对读和写两方面应用不同的优化策略

以下情况不建议使用此模式:

  • 域或业务规则非常简单。
  • 简单的 CRUD 样式用户界面和数据访问操作就足够了。

总结

本文简单的介绍了CQRS是什么,为啥要用,以及优缺点。在实际使用过程中,CQRS往往会结合事件溯源Event Sourcing一起使用的。这个在本篇文章里没有详细展开,有兴趣的同学可以自行搜索资料进行拓展阅读,我也会在后面整理相关资料,以及配上对应的工程实例帮助大家理解。

以上是关于浅谈CQRS的主要内容,如果未能解决你的问题,请参考以下文章

浅谈命令查询职责分离(CQRS)模式

浅谈命令查询职责分离(CQRS)模式

DDD CQRS架构和传统架构的优缺点比较

DDD CQRS架构和传统架构的优缺点比较

DDD CQRS架构和传统架构的优缺点比较

DDD CQRS架构和传统架构的优缺点比较