CQRS距你有多远?

Posted ImportSource

tags:

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


前面两集(,)翻译了Chris的大作。为了保证原意不跑偏同时通俗易懂,着实费了老大劲。今天我想把自己对CQRS的理解再用大白话说出来,与没时间看长文的各位共享。


毫无疑问。CQRS是治愈微服务分布式查询的良药之一。


CQRS核心的内容就是:把写入和读取分离。也就是,Command Query Responsibility Segregation,命令查询责任分离。


还是得从背景说起,我们都知道每个微服务应用都有自己的数据。那么你如果想要像关系数据库那样把两个微服务的数据join到一块,你也许会想到的是通过业务逻辑来拼接组装,这显然是一个不归路,复杂到你难以想象。


这时候你也许又会想出一条路,既然在业务逻辑中拼接比较费劲。既然跨服务查询这么费劲,那就不跨服务呗。你也许会想到把要join的数据提前就join好然后放在一个库中。到时候要查询的时候直接查出来不就得了。


对了,这就是CQRS的做法。CQRS通过数据冗余的做法来保证查询的方便。


还记得鲁迅曾说过:很多时候,我们可以倾向于读取优先写入的设计方式。



好吧,嗯,CQRS正是这种设计思想。为了查询方便,我们的写入就只能为查询服务了。这时候就需要写入的时候多insert和update几个库了。


这对关系数据库的支持者来说,简直不可思议加不可理喻。这种做法在他们看来简直就是颠覆了长久以来构建的三观。


好,回到正题,CQRS就是通过在写入时构建好查询库,然后解决了微服务中的查询问题。


那么写入的时候是怎么实现的呢?


就是通过冗余写入来实现。


不仅仅要去写入到基本表,而且还要同时把数据写入或更新到专门用于读取的读取数据库中的读取表。


那么这么多的写入,是通过在业务逻辑中挨个的写入吗?当然不是。我们可以通过发布事件的方式来。只需要发布一个事件,然后让相关的读取库都去订阅这个事件来达到实时更新读取库的目的。


上面的这个发布事件的动作,或者在MQ领域中叫做“生产一条消息”,或者在设计模式中的命令模式中称作一条“命令”。没错。这个动作就是Command。


也就是命令查询责任分离,CQRS,这个名词的由来。


另外之所以这样叫,之所以说命令和查询责任分离。说明在过去的数据持久化中,人们还是把命令和查询合并到一块来设计的。什么意思呢?就是人们一直以来认为和信息系统交互,主要就是CRUD 数据存储,而且也通常不会在中间加个EVENT BUS。


我们心中总是存在那么一个数据记录模型:我们在这个模型下,可以创建记录、读取记录、更新记录以及删除记录。


在最简单的情况下,我们的主要动作都是围绕着这些记录来做文章,存储记录和查询这些记录。


所以传统的这种数据持久化方式我们可以认为是一种“命令和查询责任合一”的  方式。


这也许是Greg Young当初起名叫CQRS的原因吧(Greg Young发明了此概念)。


CQRS把写入和查询彻底解耦分离。下面还是上一张图吧:





基本上就是上图中展示的样子,分为两个部分:命令侧和查询侧。命令侧也就是写入侧。命令侧发布事件,查询侧订阅事件,然后更新查询库。


那么这么做有什么好处呢?


好处之一就是微服务的查询问题解决了。让查询变得更加简单。

好处之二就是让微服务的数据库有了更多的选择。当然了,这个是互为因果的。正是因为微服务,才让我不得不使用CQRS;也正是因为CQRS,也使得我们的微服务中的微存储具有了更多的选择,关系数据库、NoSQL数据库等等。


CQRS,毫无疑问是个好东西,也毫无疑问增加了程序的复杂度。


CQRS使用事件驱动,


CQRS打破了传统的CRUD,


CQRS不再钟情于关系数据库,


CQRS......


CQRS距你有多远?


好吧,就说这么多,CQRS具体内容请移步后半部分。

以上是关于CQRS距你有多远?的主要内容,如果未能解决你的问题,请参考以下文章

浅谈CQRS

CQRS+ES项目解析01-Diary.CQRS

你真的了解什么是CQRS吗?

DDD领域驱动设计:CQRS架构模式

如何写出简洁的 CQRS 代码?

在 PHP 中实现 CQRS