首页/数据/数据工程与 ETL 速查/重放去重:至少一次语义兜底
CDC 与同步53 条

重放去重:至少一次语义兜底

CDC 链路多为至少一次投递:作业重放、位点回退、消费者重平衡都会重复送同一变更。去重可在目标端(主键 upsert 最省事)、加工层(按主键与位点去重,状态存最近窗口)或消息层(Kafka 事务/幂等生产者,只覆盖链路段)实现。

去重位置

层面做法代价
目标端主键 upsert / MERGE目标需要主键约束
加工层按 主键+位点 去重,保留最近窗口状态内存受规模限制
消息层Kafka 幂等/事务生产者只覆盖 Kafka 消费段
调度层回补任务设计为可重复执行全量重算成本较高

按位点去重的 SQL 思路

按位点去重的 SQL 思路
SELECT pk, file_name, pos, op
FROM (
  SELECT pk, file_name, pos, op,
         ROW_NUMBER() OVER (PARTITION BY pk, file_name, pos ORDER BY ts_ms DESC) AS rn
  FROM stage_cdc_events
) t
WHERE t.rn = 1;
去重窗口要设上限:无界状态会让长跑作业内存持续增长。

易错点

  • 只对 insert 去重,update/delete 重放后数据状态回退
  • 去重状态无限增长,作业跑几周后内存告警

数据来源与参考

  • Kafka 官方文档(Delivery semantics)
  • Debezium 官方文档(至少一次投递说明)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌