当我们系统中的数据模型层级较少时,数据模型足够简单时,模型与数据库可以直接进行映射。这种简单数据模型使我们不需要针对其相互关系进行复杂的建模设计,直接在工程中使用经典的三层模型就足以支撑项目需求。
成都创新互联公司是专业的泾源网站建设公司,泾源接单;提供网站建设、网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行泾源网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
对于这种简单系统,过度设计会增加后续维护、重构的成本(并不能保证预设计能完美符合后续需求)。同时,对于简单系统,我们大部分的需求都只涉及其中的少量数据模型逻辑处理。
而我们直接对数据模型进行CURD就能满足需求,进而的结论就是:
如果我们的系统具有一定复杂性,这种复杂性可能是源于访问频次、数据量或者是数据模型数量。这时候我们遇到的问题是数据在查询和更新的需求差距逐渐变大。
根据以上举例我们可以发现,当我们的需求具有一定的复杂性后,根据引入复杂性的不同,会导致系统功能上需要用更加复杂的设计来对需求的复杂性进行支撑。同时我们也可以发现,引入的不同复杂性在增删改和查询方面的带来的功能需求差别很大。
所以:
如果我们对系统整体的构建与设计有了更高的可维护性与可扩展性要求,以至于我们需要使用DDD来设计整个系统。
在这种情况下往往模型中具有相对复杂的模型关系,在增删改时我们需要将所有请求封装为领域对象,以便程序可以基于领域模型完成大量复杂的校验、业务逻辑。而在查询需求时,我们常常需要组织跨领域数据来完成一个列表中数据内容的展示。所以:
根据第一节中的内容我们可以发现,在进行系统架构设计时,当系统出现复杂性后存在一个核心问题:
这种差异带来的直接结果就是在系统开发的过程中,针对增删改和查询操作的业务设计上差异会比较大。如果举几个例子来说的话,比如:
由于存在增删改与查询逻辑有差异的这个问题,为了更好的针对差异进行抽象,我们可以将它们分开进行设计。也就是我们的CQRS模式,即命令查询的责任分离Command Query Responsibility Segregation模式。其中我们称增删改为命令型操作。
CQRS本质上是一种读写分离设计思想,这种框架设计模式将命令型业务和查询型业务分开单独处理。通过这种方式,CQRS可以针对命令和查询单独进行业务模型上的设计,从而用更加适合各自场景的方案与组件来提供能力。
查询操作并不会修改数据库中的内容,所以查询本身是一种幂等操作,以同一个查询条件在系统不改变的情况下反复执行会返回相同的结果,我们可以针对这种特性提供数据缓存来提高系统性能;同时因为不影响数据库,查询逻辑是不会产生数据一致性问题。查询往往会存在较高的使用频率。
命令操作会直接修改数据库,并针对多个领域模型的情况下我们需要增加来保证操作的原子性。而对于一个命令操作,我们往往是不直接依赖命令的返回值的,所以通常可以异步执行命令操作。对于一般系统来说,往往命令操作的使用频次会较低。
由于CQRS的本质是对于读写操作的分离,所以比较简单的CQRS的做法是:
这种做法在不对数据库进行分离设计的情况下,CQ两端在上层代码进行分离个字单独维护,例如命令型的都用xxxManagerController、xxxManagerService来定义,而查询则直接用xxxController、xxxService定义。
因为使用同一个数据库,所以没有CQ两端的数据一致性问题。但因为已经对上层代码进行了抽离,所以可以满足一些设计特性如:
这种方案可以满足代码逻辑上的分离维护,但由于是使用同一数据库表,所以无法根据CQ两种业务的特点单独进行模型设计。
在代码分离的基础上,我们可以再将数据存储的模型进行物理分离,读取存储可以是写入存储的只读副本,使用多个只读副本可以提高查询性能;也可能为读取模型单独设计库表。单独对查询和更新进行模型设计可以减小设计和实现的难度。并且此时读取数据库可使用自己的已针对查询进行优化的数据架构。比如读数据库可以直接存储查询数据宽表从而避免进行join操作或者复杂的查询映射。甚至可以针对读取操作使用mongo或者es等nosql数据库对查询逻辑进行增强。
分离后的数据将存在在不同的数据库中,Q的数据由C端同步过来。通常,这是通过在每次更新数据库时使写入模型发布事件来实现的。 而说到数据同步则就有同步执行和异步执行两种方案:
同样的,这种同步也可以解释为对缓存进行的更新,即:查询数据库是使用缓存,而写入数据库使用普通MySQL,两者之间数据同步通过领域事件实现最终一致性。
进一步的,由于命令操作实际上是对“操作”进行的记录,而只有查询才需要将所有的操作进行汇总展示。基于这种思想,可以使用事件溯源EventSourcing模式来进行命令操作的记录。在这种方案下,保存记录时更新的不是当前的记录,而是会导致状态变化的事件日志,每个事件表示对数据所作的一系列更改,而我们可以通过重播事件构造数据当前的状态(可以参考Mysql的Binlog设计)。这种记录的优点是可以根据回放,重现每一次状态变更的时间点以及变更轨迹。而查询则可以根据当前状态的快照来为查询提速。来自于网络的架构图:
这种设计模式听起来就比较复杂,但是却有很多好处,例如:实现透明的分布式处理,当使用事件作为状态改变的引擎时,你可以通过实现多任务并发处理,比如通过JVM并行计算或事件消息总线机制,事件能够很容易序列化,并在多个服务器之间传送。同时因为是保留的操作记录,可以在回放的时候对于异常操作数据进行过滤,从而增加了数据的鲁棒性。
如果希望使用CQRS,根据你希望实现的系统性能,你需要评估当前系统架构以及个人经验是否有以下能力:
对于以下场景不建议引入CQRS:
如果系统存在一定的复杂性,并且有以下的特点,则可以根据特点,选择适合的CQRS实现方式。
总的来说,CQRS是处理复杂问题的一种具体实现方案,常用于配合DDD使用。
总结CQRS 的主要优点包括:
新闻标题:一篇带你了解一下CQRS模式
本文来源:http://www.gawzjz.com/qtweb2/news26/22726.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联