命令查询职责分离 (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,多数据库管理平台(私有云)。

相关推荐
dazhong201233 分钟前
PLSQL 客户端连接 Oracle 数据库配置
数据库·oracle
路在脚下@1 小时前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
了一li3 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
盛派网络小助手3 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
码农君莫笑3 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
别致的影分身3 小时前
使用C语言连接MySQL
数据库·mysql
京东零售技术5 小时前
“慢”增长时代的企业数据体系建设:超越数据中台
数据库
sdaxue.com5 小时前
帝国CMS:如何去掉帝国CMS登录界面的认证码登录
数据库·github·网站·帝国cms·认证码
o(╥﹏╥)6 小时前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
阿里嘎多学长6 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器