CDC 数据同步架构:如何把业务库安全同步到 OLAP
CDC 不是简单搬数据,它要处理全量快照、增量日志、Schema 变更、乱序事件、重复投递和下游幂等写入。
CDC 数据同步架构:如何把业务库安全同步到 OLAP
CDC 是 Change Data Capture,变更数据捕获。它的目标是捕获业务数据库里的 insert、update、delete,然后把这些变化同步到搜索、缓存、OLAP、数据湖或其他下游系统。
对于数据库系统专栏来说,CDC 是连接 OLTP 和 OLAP 的关键桥梁。业务库负责交易,OLAP 负责分析,中间就需要一条稳定的数据同步链路。
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、重复、乱序、删除、延迟、对账和回放。