CQRS 是什么
CQRS 把写模型(命令)与读模型(查询)分开,各自采用不同的结构与存储:写侧专注业务规则与不变量,读侧针对查询需要组织宽表或索引。它让读写可以独立扩展与优化,尤其适合读写比例悬殊、查询形态复杂的系统。代价是读侧通常最终一致,需要额外的同步机制、延迟监控与故障补偿。
读写对比
| 维度 | 命令侧 | 查询侧 |
|---|---|---|
| 职责 | 校验、变更、发布事件 | 按查询需求组织数据 |
| 模型 | 领域模型,保证不变量 | 面向视图的宽表或索引 |
| 一致性 | 强一致 | 通常最终一致 |
| 扩展 | 写扩展相对困难,需谨慎分片 | 读可多副本水平扩展 |
| 存储 | 关系库居多,事务能力强 | 搜索索引、缓存、列存等按需选择 |
基本信息
| 同步方式 | 同步双写、领域事件、变更数据捕获(CDC)均可 |
|---|---|
| 一致性窗口 | 从写入到读侧可见的时间差需明确并监控 |
| 补偿手段 | 对账任务、读侧重放、手工修复入口 |
| 常见组合 | 常与事件溯源、事件驱动架构搭配使用 |
| 落地底线 | 读侧必须可重建,避免成为唯一数据来源 |
典型使用场景
- 读写比例悬殊:读远多于写的商品、资讯类系统
- 多形态查询:同一份数据要支持列表、聚合、全文检索等多种视图
- 报表与统计:写侧保持事务模型,读侧建专门的汇总表
- 隔离压测:读流量激增时不影响写链路
- 审计要求:写侧保留完整命令轨迹,便于追溯
- 大促场景:读写分别按各自峰值扩容,成本更可控
不适用的情况
- 读写比例接近且模型简单:分离带来的同步成本高于收益
- 业务无法接受任何读延迟:只能用同一存储强一致读取
- 团队缺少消息与补偿运维能力:读侧故障难以定位与恢复
- 一次读要跨多写模型聚合且要求强一致:读侧无法独立满足
CQRS 是读写分离的强化版:单纯的读写分离仍共用同一数据模型,CQRS 允许两侧模型完全不同,因此读侧必须能重建而不只是复制。
读侧数据成为唯一来源后若发生同步中断,业务会读到过期数据且无依据修复,必须保留可重建路径。