CQRS 与事件溯源:后端架构的进阶之路

116 阅读3分钟

1. 背景

在传统架构中,系统通常使用 单一数据模型 处理读写:

  • 写入:更新数据库中的一条记录
  • 读取:查询同一张表返回数据

这种模式的问题是:

  • 读写冲突:高并发场景下,读和写争抢数据库资源
  • 难以扩展:同一数据模型既要支撑事务写入,又要支撑复杂查询
  • 历史丢失:只保存最新状态,无法还原数据变化过程

为了解决这些问题,出现了 CQRS + Event Sourcing(事件溯源) 架构模式。


2. 什么是 CQRS?

CQRS 全称 Command Query Responsibility Segregation,即 命令与查询职责分离

  • 命令(Command) :修改系统状态(写操作)
  • 查询(Query) :读取系统状态(读操作)

👉 在 CQRS 架构中,写模型和读模型分离:

  • 写入模型保证业务逻辑和一致性
  • 读取模型可以为性能和多样化查询优化(甚至用不同数据库)

3. 什么是事件溯源(Event Sourcing)?

事件溯源的核心思想是:
👉 系统状态不是直接存储,而是由一系列事件计算得出。

  • 写入时:不是直接更新数据库,而是记录“事件”
  • 查询时:通过事件重放或投影得到最新状态

例如:

传统模式:余额 = 100
事件溯源:存入 50 → 支出 30 → 存入 80 → 最终余额 = 100

这意味着:

  • 可以回放事件,重建任意时刻的状态
  • 业务更可追溯,可用于审计与合规

4. CQRS + 事件溯源如何结合?

两者常常搭配使用:

  1. 命令(Command) :业务逻辑执行后,生成事件(例如 “订单已创建”)
  2. 事件存储(Event Store) :事件持久化到事件日志(Kafka、EventStoreDB)
  3. 投影(Projection) :事件异步更新到查询数据库(ElasticSearch、Redis、MongoDB)
  4. 查询(Query) :读取优化后的查询模型,返回结果

这种模式让 写入模型与读取模型彻底解耦


5. 优势

  • 高扩展性:读写分离,可独立扩展查询服务
  • 多样化存储:读模型可用 Redis、ES,写模型可用关系数据库
  • 可追溯性:通过事件日志还原任意历史状态
  • 天然支持审计:金融、风控场景尤其适用

6. 挑战

  • 数据一致性:读模型异步更新,存在延迟
  • 事件存储成本:事件数量庞大,需要快照机制优化
  • 开发复杂度:开发者需要管理 Command、Event、Projection 三类逻辑
  • 学习曲线高:团队需要新的思维方式

7. 应用场景

金融系统

  • 转账、支付等操作需要完整的事件日志,方便审计与追溯。

电商订单

  • “订单已创建 → 已支付 → 已发货 → 已完成”,天然符合事件溯源模型。

IoT & 日志平台

  • 大量状态变化(传感器数据、操作日志)更适合存储为事件流。

游戏后端

  • 玩家行为事件可重放,方便调试、回放和作弊检测。

8. 实现示例

写入(Command → Event)

# 示例:订单服务
class OrderService:
    def create_order(self, order_id, user_id, items):
        event = {
            "type": "OrderCreated",
            "order_id": order_id,
            "user_id": user_id,
            "items": items
        }
        event_store.append(event)

投影(Event → Read Model)

# 示例:订单投影
def handle_order_created(event):
    read_db["orders"][event["order_id"]] = {
        "status": "CREATED",
        "user_id": event["user_id"],
        "items": event["items"]
    }

查询时,直接访问 read_db,不影响写入性能。


9. 总结

CQRS + 事件溯源让后端具备:

  • 写读解耦,高性能扩展
  • 事件驱动,可追溯历史
  • 更适合复杂业务(金融、电商、IoT)

但代价是:

  • 架构复杂度提高
  • 一致性变成最终一致
  • 对团队能力要求更高

👉 一句话总结:
CQRS + Event Sourcing 是复杂系统的“重武器”,适合规模大、合规要求高的后端系统。