命令查询职责分离 (CQRS)

CQRS 的最初需求

多年来,传统的 CRUD(创建、读取、更新、删除)模式一直是系统架构的支柱。在 CRUD 中,读取和写入操作通常由相同的数据模型和相同的数据库模式处理。虽然这种方法简单直观,但随着系统规模的扩大和需求变得更加复杂,它的效率就会降低。

例如,考虑一个拥有数百万用户的大型电子商务应用程序。该系统可能面临相互冲突的需求:它需要快速读取产品详细信息、评论和用户配置文件,但它还必须有效处理数千笔交易、库存更新和订单下达。随着读取和写入操作的增长,对两者使用单一模型可能会导致瓶颈,影响性能和用户体验。

CQRS 模式的基础知识

CQRS 的引入是为了解决这些扩展挑战。该模式的本质就在于它的名字——命令查询职责分离。在这里,命令负责系统状态的任何更改(例如下订单或更新用户配置文件),而查询则处理数据检索,没有任何副作用。

在 CQRS 系统中,这两个操作被视为完全不同的职责,通常具有单独的数据模型、数据库,甚至单独的服务器或服务。这使得每个操作都可以独立于另一个进行调整、缩放和维护,并与每个操作的特定需求保持一致。

CQRS 组件

命令

命令是在系统内执行操作或更改的指令组件。它们的命名应反映意图和上下文,例如PlaceOrder或UpdateUserProfile。重要的是,命令应该负责更改,因此不应返回数据。进一步探索命令如何处理验证、授权和业务逻辑将阐明它们在 CQRS 模式中的角色。

查询

另一方面,查询处理所有数据请求操作。重点可能在于如何构建这些来提供针对特定用例定制的优化的、非规范化的数据视图。您可以深入研究构建和优化查询服务的不同策略,以处理潜在的复杂读取模型。

命令和查询处理程序

处理程序充当促进命令和查询执行的代理。命令处理程序负责执行与数据突变相关的逻辑,同时确保遵守验证和业务规则。查询处理程序管理数据的检索,可能涉及复杂的聚合或连接以形成请求的读取模型。

单数据库与双数据库方法

单一数据库

在此模型中,命令和查询操作都在单个数据库上执行,但具有不同的模型或模式。即使这两个操作共享相同的物理存储,它们也可能使用针对其特定要求而优化的不同表、视图或索引。

它可以表示如下:

图片

好处

  • 简化基础设施并减少开销

  • 立即一致性,因为写入和读取操作之间没有延迟

权衡

  • 在大量并发操作期间,共享资源仍然可能成为瓶颈。

  • 独立调整和缩放操作的灵活性较低

双数据库方法

在这里,命令和查询操作完全分开,使用两个不同的数据库或存储系统。写数据库专用于处理命令,而读数据库则服务于查询操作。必须添加手柄同步系统。

它可以表示如下:

图片

好处

  • 每个操作的单独调整、缩放和优化

  • 每个数据库有可能托管在不同的服务器或服务上,分配负载;数据库解决方案也可能有所不同,以便为特定需求提供更多的模块化。

权衡

  • 为确保两个数据库之间的数据一致性带来了复杂性

  • 需要同步机制来桥接写入和读取数据库之间潜在的错位或延迟:例如,写入操作可能会更新命令数据库,但读取数据库可能不会立即反映这些更改。为了解决这个问题,同步技术的范围可以从简单的轮询到更复杂的方法,例如事件源,其中修改被捕获为一系列事件并重放以更新读取的数据库。

单一数据库方法提供了简单性;双数据库配置提供了更大的灵活性和可扩展性,但代价是增加了复杂性。这些方法之间的选择取决于相关系统的具体要求和挑战,特别是围绕性能需求和一致性要求。

CQRS 模式的优点和权衡

好处

  • 性能优化:通过分离读写逻辑,可以独立扩展和优化各个方面。例如,如果系统读取量很大,您可以分配更多资源来处理查询,而不会因写入操作的需求而陷入困境。

  • 灵活性和可扩展性:通过单独的读取和写入模型,可以更轻松地在一个模型中引入更改,而不会影响另一个模型。这种隔离不仅可以实现更敏捷的开发和更轻松的可扩展性,还可以针对与急切实体加载相关的常见问题提供保护。通过明确地处理读取和写入,可以优化系统以避免不必要的数据加载,从而提高性能并减少资源消耗。

  • 简化的代码库:分离命令和查询逻辑可以使代码库更易于维护且不易出错。每个模型都有明确的职责,减少了由于相互交织的逻辑而引入错误的可能性。

权衡

  • 数据一致性:由于读写模型可能不同,实现数据一致性可能具有挑战性。CQRS 通常与“最终一致性”模型齐头并进,这可能并不适合所有应用程序。

  • 复杂性开销:引入 CQRS 会增加复杂性,尤其是与事件溯源等其他模式配合使用时。评估所获得的好处是否超过增加的复杂性至关重要。

  • 增加开发工作量:拥有独立的读写模型本质上意味着维护系统的两个不同部分。这会增加初始开发工作量以及持续的维护开销。

结论

CQRS 提供了一种变革性的数据管理方法,在性能、可扩展性和代码清晰度方面带来了显着的优势。然而,这并不是灵丹妙药。与所有架构决策一样,采用 CQRS 应该是一个经过深思熟虑的选择,要考虑到它的好处和它带来的挑战。对于可扩展性和性能至关重要且可以接受权衡的系统,CQRS 可以改变游戏规则,将系统的稳健性和响应能力提升到新的高度。


作者:Artem Artemev

更多技术干货请关注公号【云原生数据库

squids.cn,云数据库RDS,迁移工具DBMotion,云备份DBTwin等数据库生态工具。

irds.cn,多数据库管理平台(私有云)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第99步 深度学习图像目标检测:SSDlite建模

基于WIN10的64位系统演示 一、写在前面 本期,我们继续学习深度学习图像目标检测系列,SSD(Single Shot MultiBox Detector)模型的后续版本,SSDlite模型。 二、SSDlite简介 SSDLite 是 SSD 模型的一个变种&#xff0c…

竹云参编《公共数据授权运营平台技术要求》团体标准正式发布

2023年11月23日,第二届全球数字贸易博览会“数据要素治理与市场化论坛”于杭州成功召开,国家数据局党组书记、局长刘烈宏,浙江省委常委、常务副省长徐文光出席会议并致辞。会上,国家工业信息安全发展研究中心发布并解读了我国首部…

[Linux] 冯诺依曼体系结构 与 操作系统

文章目录 1、冯诺依曼体系结构2、操作系统 1、冯诺依曼体系结构 冯诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置,因此程序指令和数据的宽度相…

【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区三级联动地址选择器组件(下)

文章目录 概述端云调用流程端侧集成AGC SDK端侧省市地区联动的地址选择器组件开发创建省市数据模型创建省市地区视图UI子组件创建页面UI视图Page文件 打包测试总结 概述 我们在前面的课程,对云开发的入门做了介绍,以及使用一个省市地区联动的地址选择器…

三次输错密码后,系统是怎么做到不让我继续尝试的?

1故事背景 忘记密码这件事,相信绝大多数人都遇到过,输一次错一次,错到几次以上,就不允许你继续尝试了。 但当你尝试重置密码,又发现新密码不能和原密码重复: 图片 相信此刻心情只能用一张图形容&#xf…

Mobaxterm 使用lrzsz传输文件(rz/sz)

Mobaxterm 使用lrzsz传输文件报错 1. 现象 最近从xshell切换到Mobaxterm其他一切正常,就是使用rz传输文件时会出现错误,比较苦恼. 会出现以下错误 [rootcentos7 rpmbuild]# rz ▒CCCCCCCCCCC23be50ive.**B0100000023be502. 解决方法 去官网(https://mobaxterm.mobatek.net…

2021年03月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 在《采矿》游戏中,当角色捡到黄金时财富值加1分,捡到钻石时财富值加2分,下面哪个程序实现这个功能? A: B: C: D: 答案:D A将变量值固定,BC为双重判断

练习七-在Verilog中使用任务task

在Verilog中使用任务task 1,任务目的2,RTL代码,交换3,测试代码4,波形显示 1,任务目的 (1)掌握任务在verilog模块设计中的应用; (2)学会在电平敏感…

Android Studio记录一个错误:Execution failed for task ‘:app:lintVitalRelease‘.

Android出现Execution failed for task :app:lintVitalRelease.> Lint found fatal errors while assembling a release target. Execution failed for task :app:lintVitalRelease解决方法 Execution failed for task ‘:app:lintVitalRelease’ build project 可以正常执…

〖大前端 - 基础入门三大核心之JS篇㊷〗- DOM事件对象及它的属性

说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

进程已结束,退出代码-1073741571 (0xC00000FD)

今天遇到了一个很邪门的问题,没有报错,只是提示“进程已结束,退出代码-1073741571 (0xC00000FD)”。后来查资料说是栈溢出。 出问题的应该是上面这段代码。 这里我想把一个128*128的矩阵进行剪枝操作。 传入的128*128的矩阵太大了,两组for循…

【Flink】状态管理

目录 1、状态概述 1.1 无状态算子 1.2 有状态算子 2、状态分类 ​编辑 2.1 算子状态 2.1.1 列表状态(ListState) 2.1.2 联合列表状态(UnionListState) 2.1.3 广播状态(BroadcastState) 2.2 按键分…

图像标记上线,描点信息尽在掌握丨三叠云

图像标记 路径 表单设计 >> 组件 >> 增强组件 功能简介 「图像标记」字段是「增强字段」类型字段。用户通过上传图片的方式构建一个背景图片,并在构建的图片背景上添加描点信息。搭配「仪表盘」中的「图像轨迹」,可绘制出相应的数据轨迹…

界面组件DevExpress Reporting v23.1 - Web报表设计器功能升级

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v23.1已经发布一段…

基于JavaWeb+SSM+Vue微信阅读小程序的设计和实现

基于JavaWebSSMVue微信阅读小程序的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏[Java 源码获取 源码获取入口 Lun文目录 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 1 第2章 开发环境与技术 3 2.1 MYSQL数据库 3 2.2 JSP技…

2016年8月15日 Go生态洞察:Go 1.7版本发布

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

解决traefik/nginx-ingress-controller配置正确的情况访问域名仍然报错: Connection Refused的问题

最近碰到一个很奇怪的问题: traefik/nginx-ingress-controller配置正确,但是访问ingress配置的host域名就是死活报错: Connection Refused 这样怎么也找不到原因,然后一咬牙直接在其中一台节点yum安装nginx, 通过直接反向代理的方…

微信小程序开发资源汇总

本文收集了微信小程序开发过程中会使用到的资料、问题以及第三方组件库。本文不是一篇关于如何学习微信小程序的入门指南,也非参考手册,只是一些资料的整理。 本仓库中的资料整理自网络,也有一些来自网友的推荐。 官方文档 小程序设计指南…

UE5 UI教程学习笔记

参考资料:https://item.taobao.com/item.htm?spma21n57.1.0.0.2b4f523cAV5i43&id716635137219&ns1&abbucket15#detail 基础工程:https://download.csdn.net/download/qq_17523181/88559312 1. 介绍 工程素材 2. 创建Widget UE5 UI系统的…

那些被玩烂了的设计模式

单例模式 单例模式是指一个类在一个进程中只有一个实例对象(但也不一定,比如Spring中的Bean的单例是指在一个容器中是单例的) 单例模式创建分为饿汉式和懒汉式,总共大概有8种写法。但是在开源项目中使用最多的主要有两种写法&am…