首页/开发/系统分析与架构设计速查/CQRS 命令查询职责分离
架构风格与模式58 条

CQRS 命令查询职责分离

把写模型(命令)与读模型(查询)分离,各自可采用不同结构与存储;读侧可针对查询优化,写侧专注于一致性与业务规则,代价是最终一致与复杂度。

CQRS 是什么

CQRS 把写模型(命令)与读模型(查询)分开,各自采用不同的结构与存储:写侧专注业务规则与不变量,读侧针对查询需要组织宽表或索引。它让读写可以独立扩展与优化,尤其适合读写比例悬殊、查询形态复杂的系统。代价是读侧通常最终一致,需要额外的同步机制、延迟监控与故障补偿。

读写对比

维度命令侧查询侧
职责校验、变更、发布事件按查询需求组织数据
模型领域模型,保证不变量面向视图的宽表或索引
一致性强一致通常最终一致
扩展写扩展相对困难,需谨慎分片读可多副本水平扩展
存储关系库居多,事务能力强搜索索引、缓存、列存等按需选择

基本信息

同步方式同步双写、领域事件、变更数据捕获(CDC)均可
一致性窗口从写入到读侧可见的时间差需明确并监控
补偿手段对账任务、读侧重放、手工修复入口
常见组合常与事件溯源、事件驱动架构搭配使用
落地底线读侧必须可重建,避免成为唯一数据来源

典型使用场景

  • 读写比例悬殊:读远多于写的商品、资讯类系统
  • 多形态查询:同一份数据要支持列表、聚合、全文检索等多种视图
  • 报表与统计:写侧保持事务模型,读侧建专门的汇总表
  • 隔离压测:读流量激增时不影响写链路
  • 审计要求:写侧保留完整命令轨迹,便于追溯
  • 大促场景:读写分别按各自峰值扩容,成本更可控

不适用的情况

  • 读写比例接近且模型简单:分离带来的同步成本高于收益
  • 业务无法接受任何读延迟:只能用同一存储强一致读取
  • 团队缺少消息与补偿运维能力:读侧故障难以定位与恢复
  • 一次读要跨多写模型聚合且要求强一致:读侧无法独立满足
CQRS 是读写分离的强化版:单纯的读写分离仍共用同一数据模型,CQRS 允许两侧模型完全不同,因此读侧必须能重建而不只是复制。
读侧数据成为唯一来源后若发生同步中断,业务会读到过期数据且无依据修复,必须保留可重建路径。

易错点

  • 把 CQRS 当默认架构,读写比例接近的业务白白承担同步与运维成本
  • 读侧无重建能力,同步链路中断后数据只能人工逐条修补
  • 一致性窗口无监控,用户下单后立即查询看不到订单,被当成 Bug 反复排查
  • 写侧模型为查询方便而变形,失去不变量约束,业务规则无处安放
  • 同步用双写且无补偿,任一侧写入失败即产生永久数据分叉

数据来源与参考

  • Martin Fowler bliki《CQRS》
  • Greg Young CQRS 文献与演讲
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌