CDC 数据同步架构:如何把业务库安全同步到 OLAP

CDC 不是简单搬数据,它要处理全量快照、增量日志、Schema 变更、乱序事件、重复投递和下游幂等写入。

CDC 数据同步架构:如何把业务库安全同步到 OLAP

CDC 是 Change Data Capture,变更数据捕获。它的目标是捕获业务数据库里的 insert、update、delete,然后把这些变化同步到搜索、缓存、OLAP、数据湖或其他下游系统。

对于数据库系统专栏来说,CDC 是连接 OLTP 和 OLAP 的关键桥梁。业务库负责交易,OLAP 负责分析,中间就需要一条稳定的数据同步链路。

Rendering diagram...

CDC 解决什么问题

最朴素的数据同步方式是定时轮询。比如每分钟查一次 updated_at > last_time 的数据。但这种方式容易漏数据、重复数据,也不容易捕获删除事件。

CDC 直接读取数据库变更日志。MySQL 主要基于 binlog,PostgreSQL 主要基于 WAL 和逻辑复制。这样可以更完整地获得行级变更。

全量快照和增量同步

CDC 通常分两步:

第一步是全量快照。把当前表里的历史数据完整同步到下游。

第二步是增量同步。从某个 binlog position 或 WAL LSN 开始持续读取新增变更。

难点在于全量和增量如何无缝衔接。如果全量扫描过程中业务还在写入,系统必须保证既不漏掉扫描期间发生的变更,也不重复造成错误结果。

Debezium 事件结构

Debezium 通常会把数据库变更转换成统一的事件结构。一个 update 事件可以抽象成:

{
  "op": "u",
  "before": {
    "id": 10001,
    "status": "CREATED"
  },
  "after": {
    "id": 10001,
    "status": "PAID"
  },
  "source": {
    "db": "shop",
    "table": "orders"
  },
  "ts_ms": 1780000000000
}

before 表示变更前,after 表示变更后,op 表示操作类型。下游可以根据这些字段更新宽表、聚合表或搜索索引。

同步到 OLAP 的几种方式

第一种是 CDC 直接写 OLAP。链路短,但清洗、转换和错误处理能力有限。

第二种是 CDC 写 Kafka,Flink 消费 Kafka 后再写 OLAP。这是实时数仓常见方式,灵活度高,能做清洗、维表关联、聚合和幂等处理。

第三种是 CDC 写数据湖,再由 OLAP 外表或湖仓引擎查询。这适合大规模历史数据和成本敏感场景。

Schema 变更

业务库会加字段、改类型、删字段。CDC 链路必须面对 Schema 变更。

加字段通常比较容易,下游可以先允许空值。改类型和删字段风险更高,可能导致消费者解析失败或 OLAP 写入失败。

比较稳妥的做法是:

  • Schema 变更先评审。
  • 下游表先兼容新字段。
  • 消费端支持忽略未知字段。
  • 删除字段分阶段进行。

重复、乱序和删除

CDC 链路可能重复投递。下游写入需要幂等,尤其是主键表、更新表或宽表。

事件也可能乱序。比如订单先支付后取消,如果下游先收到取消再收到支付,就会把状态写错。因此事件里最好带版本号、更新时间或 binlog 位点。

删除事件也要明确处理。OLAP 里是物理删除、逻辑删除,还是保留删除标记,取决于分析需求。

CREATE TABLE order_cdc_sink (
  order_id BIGINT,
  status STRING,
  updated_at TIMESTAMP,
  op STRING,
  PRIMARY KEY (order_id) NOT ENFORCED
);

主键写入模型可以让下游按 order_id 更新最新状态,但要注意不同 OLAP 数据库对主键更新的实现差异。

监控指标

CDC 链路必须监控:

  • 源库日志位点。
  • Kafka 堆积。
  • 消费延迟。
  • 写入失败数。
  • Schema 解析失败。
  • 下游数据量波动。
  • 源表和目标表对账结果。

没有监控的 CDC 链路很危险。它可能悄悄停掉,然后报表继续展示旧数据。

小结

CDC 是业务库到分析系统的关键通道。它看起来像同步工具,实际上是数据一致性工程。

真正可靠的 CDC 架构,需要同时处理全量、增量、Schema、重复、乱序、删除、延迟、对账和回放。

参考链接