增量计算核心概念:变更数据捕获(CDC)、增量标识、时间戳与版本号机制

聊增量计算,绕不开三个核心概念:变更数据捕获(CDC)、增量标识、以及时间戳与版本号机制。这三个东西,说白了就是增量计算的“眼睛”、“身份证”和“日历本”。

我刚开始做主数据项目时,也踩过不少坑。有一次全量同步把生产库拖垮了,DBA 差点没把我骂死。从那以后,我才真正重视起增量更新。今天咱们就把这三个概念掰开揉碎,讲清楚。

1. 变更数据捕获(CDC)——增量计算的“眼睛”

CDC 是什么?简单说,就是盯着数据源,看哪些数据变了。它不关心存量数据,只关心增量变化。

我习惯把 CDC 分成两类:

  • 基于日志的 CDC:直接读数据库的事务日志(比如 MySQL 的 binlog、Oracle 的 redo log)。性能好,对源库几乎无侵入。
  • 基于轮询的 CDC:定时查表,比对时间戳或版本号。实现简单,但延迟高,对源库有压力。

核心观点:生产环境,我强烈推荐基于日志的 CDC。虽然配置复杂点,但不会漏数据,也不会把源库搞崩。

举个例子,我之前帮一家电商公司做主数据平台。他们用 MySQL 存商品信息,每天几百万条更新。一开始用轮询方式,每 5 分钟扫一次全表,结果数据库 CPU 直接飙到 90%。后来换成 Debezium 监听 binlog,CPU 降到 5%,延迟也控制在秒级。

我的经验:选 CDC 工具时,先看源库类型。MySQL 用 Debezium + Kafka,Oracle 用 GoldenGate,SQL Server 用 Change Tracking。别盲目追求统一方案。

2. 增量标识——给每条数据一个“身份证”

有了 CDC,我们知道了“哪些数据变了”。但怎么区分“这是新增”、“这是修改”、“这是删除”?这就需要增量标识。

常见的增量标识有三种:

标识类型 实现方式 优点 缺点
操作类型字段 在数据中加一个字段,如 op_type: 'I'/'U'/'D' 直观,容易理解 需要业务系统配合改造
变更日志表 单独建一张变更表,记录主键、操作类型、变更时间 不影响原表结构 需要额外存储和维护
CDC 事件类型 利用 CDC 工具自带的事件类型(如 Debezium 的 create/update/delete) 无侵入,自动化 依赖 CDC 工具

我个人习惯用CDC 事件类型 + 变更日志表的组合。为什么?因为 CDC 事件类型能实时捕获变化,变更日志表可以做历史回溯。万一数据对不上,还能查查“当时到底发生了什么”。

避坑指南:我曾经遇到过一个坑——只用操作类型字段,但业务系统改了数据后忘了更新这个字段。结果增量计算把修改当成了新增,导致主数据里出现了大量重复记录。所以,增量标识最好由 CDC 层自动生成,不要依赖业务系统。

3. 时间戳与版本号机制——增量计算的“日历本”

时间戳和版本号,是增量计算中最常用的两种“边界标记”。它们决定了“从哪开始抓增量”。

3.1 时间戳机制

原理很简单:每条数据记录一个最后修改时间(last_modified_time)。增量计算时,只取 last_modified_time > 上次同步时间 的数据。

嗯,这里要注意:时间戳机制有个精度问题。如果两条数据在同一毫秒内被修改,时间戳一样,就可能漏掉一条。我遇到过这种情况,最后排查了半天才发现是时间戳精度不够。

我的建议:时间戳精度至少到毫秒级。如果数据库支持,用微秒或纳秒更好。另外,时间戳字段一定要建索引,不然全表扫描会慢死。

3.2 版本号机制

版本号机制,说白了就是给每条数据一个递增的整数。每次修改,版本号加 1。增量计算时,只取 version > 上次同步的版本号 的数据。

版本号的好处是有序,不会出现时间戳的精度问题。但坏处是,如果数据分布在多个节点上,版本号的全局递增会比较麻烦。

对比维度 时间戳机制 版本号机制
有序性 依赖系统时钟,可能有偏差 有序,无偏差
精度问题 高并发下可能丢失变更 不会丢失
分布式支持 好,各节点独立 差,需要全局协调
实现复杂度 低 中

你想想看,如果系统是单库单表,版本号机制更靠谱。如果是分布式架构,时间戳机制更灵活。我一般会两者结合:用时间戳做主要增量标识,用版本号做兜底校验。

4. 三者如何协同工作?

CDC、增量标识、时间戳/版本号,不是孤立的。它们是一个完整的链路:

  1. CDC 捕获变化:监听数据源,发现新增、修改、删除事件。
  2. 增量标识标记操作类型:给每个事件打上“这是新增/修改/删除”的标签。
  3. 时间戳/版本号记录边界:记录“这个事件发生在什么时间/版本”,用于增量计算的起始点。

下面这张图,展示了三者的协作关系:

CDC、增量标识、时间戳/版本号协作流程 增量计算核心概念协作流程 数据源 MySQL / Oracle / SQL Server CDC 捕获 binlog / redo log 监听 增量标识 I / U / D 标记 目标端 主数据平台 时间戳 / 版本号 记录变更边界 增量计算引擎 合并、去重、落库

从图上可以看出:CDC 负责“看”,增量标识负责“贴标签”,时间戳/版本号负责“记边界”。三者缺一不可。

5. 实战中的常见问题

最后,分享几个我在项目中遇到的坑:

  • 时间戳回拨:服务器时钟被 NTP 同步回拨,导致增量数据重复或丢失。解决方案:用逻辑时钟或版本号兜底。
  • CDC 延迟:binlog 消费太慢,导致增量数据堆积。解决方案:增加消费者并行度,或者用 Kafka 做缓冲。
  • 增量标识丢失:CDC 工具重启后,部分事件类型丢失。解决方案:在目标端做幂等处理,确保重复消费不会产生脏数据。

总结一句话:CDC 是增量计算的“眼睛”,增量标识是“身份证”,时间戳/版本号是“日历本”。三者配合好了,增量更新才能又快又稳。