CQRS 用不同模型承担写入决策与读取查询
说明命令模型、查询投影、同步延迟和一致性边界,并分析 CQRS 与事件溯源的关系及分阶段采用方式。
CQRS 用不同模型承担写入决策与读取查询
命令查询职责分离把改变状态的命令与返回数据的查询放到不同模型中。写模型围绕业务规则、授权和一致性组织,读模型围绕页面、报表或搜索所需的形状组织。它解决的是读写需求差异带来的复杂度,不等于必须拆成微服务,也不要求使用事件溯源。
在简单增删改查系统中,共享模型通常更容易维护。只有当写入规则复杂、读取形态多样、两侧扩展需求明显不同,或统一模型已形成持续阻碍时,CQRS 的额外同步和运维成本才可能合理。
命令表达意图而不是字段补丁
命令描述希望系统执行的动作,例如“确认订单”或“分配设备”,应携带验证业务规则所需的输入和调用者上下文。命令处理器先鉴权,再读取必要状态、检查不变量并提交变化。返回值通常是确认信息、资源标识或错误,而不是任意查询结果。
幂等性必须按业务动作设计。网络重试可能重复发送同一命令,可使用调用方请求标识、唯一约束或业务状态机识别重复。只在网关去重而后端没有持久化幂等记录,跨重启或并发重试仍可能重复生效。
命令不应成为绕过领域规则的通用字段更新接口。若调用方直接指定内部状态,写模型就失去保护不变量的作用。规则演进时要版本化命令契约,并明确旧客户端的兼容期。
读模型按消费场景投影
查询端可以预连接、反规范化或缓存数据,直接形成页面和报表需要的结构。这样可以避免写模型为了每一种视图不断暴露内部关系,也允许读侧独立扩容。多个读模型可服务不同延迟、搜索或聚合需求。
Microsoft Azure Architecture Center 的 CQRS 模式说明了单独读写模型、数据同步和独立扩展的取舍:https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs 。分离可以发生在代码对象、数据库模式或独立存储层,边界越远,发布和故障处理越复杂。
读模型应被视为可重建投影,而不是新的事实来源。每个字段要能追溯到权威写入状态或事件,投影版本、处理位置和重建流程需要记录。为了查询方便而在读库接受直接修改,会形成无法对账的双主状态。
同步延迟成为用户可见语义
当读写使用不同存储时,写入成功到读模型可见之间通常存在延迟。应用必须定义“成功”表示写模型已提交、消息已持久化,还是读模型已更新。前端可使用写入响应中的结果、显示处理中状态,或在指定版本到达后再刷新,不能假设立即读取必然看到新值。
可靠传播通常采用事务性发件箱:业务状态与待发送记录在同一事务提交,后台发布器再至少一次投递。读侧必须幂等处理重复消息,并保存处理位置。消息顺序只应在确有业务要求的聚合范围内保证,追求全局顺序会显著降低吞吐和可用性。
事件溯源可把事件流作为写侧事实,并从事件生成读模型,但它是独立选择。Microsoft 对 Event Sourcing 的说明展示了追加事件、重放和投影的额外复杂度:https://learn.microsoft.com/en-us/azure/architecture/patterns/event-sourcing 。普通事务数据库同样可以实现 CQRS。
一致性边界需要明确划分
单个业务聚合内的强不变量应在写事务中完成,跨聚合流程可使用状态机、补偿和显式超时。把所有规则推给最终一致的读模型,会让并发命令在陈旧状态上做决定。读侧适合展示和检索,不应承担只能由权威写状态判断的关键约束。
查询授权也不能因为数据已投影而放松。反规范化记录可能混合不同租户或敏感级别,构建投影时和读取时都要保留租户键、数据范围和策略信息。删除、更正或权限撤销必须传播到所有读模型和缓存,并有对账证明。
跨模型对账要比较业务可验证的不变量、处理位点和记录数,而非要求内部结构完全一致。监控指标包括投影延迟、积压、失败重试、死信、版本不兼容和重建进度。
采用和回滚要分阶段
可先在同一进程内分离命令与查询接口,保留同一数据库;确认模型收益后,再为高负载查询增加投影。每一步都应保留旧读路径,对新旧结果做影子比较。只有当延迟、成本或隔离收益可测量时,才继续拆分存储与部署。
投影 schema 变化应采用并行版本:建立新投影、从稳定位点回放或回填、验证后切换读取,再删除旧版本。消息消费者要能处理兼容窗口中的旧新事件。回滚不应要求逆转已发生的业务事实,而应切回旧读模型或发布补偿命令。
CQRS 的判断标准不是组件数量,而是写侧规则是否更清晰、读侧是否更高效,并且同步延迟和故障恢复是否可被用户与运维人员理解。无法承担投影重建、重复消息和最终一致性时,统一模型通常是更可靠的选择。
资料依据
- Microsoft Azure Architecture Center:CQRS Pattern,https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs
- Microsoft Azure Architecture Center:Event Sourcing Pattern,https://learn.microsoft.com/en-us/azure/architecture/patterns/event-sourcing