首页/数据/数据工程与 ETL 速查/CDC 落 Kafka 的主题设计
CDC 与同步53 条

CDC 落 Kafka 的主题设计

CDC 落到 Kafka 常按一表一主题(Debezium 默认命名为 <topic.prefix>.<库>.<表>),消息 key 用主键保证同键分区有序;表多时可路由合并主题,高变更量表按峰值吞吐规划分区数,需要“每键最新值”语义的主题可评估 compact 清理策略。

CDC 主题设计是什么

CDC 落到 Kafka 时,主题设计决定下游好不好用:常见做法是一表一主题,配合统一前缀(Debezium 默认用 topic.prefix 加库表名);消息 key 取主键,保证同一业务键的变更落在同一分区从而保持顺序;分区数按峰值写入与下游并行度规划;需要「每键最新值」语义的主题可评估 compact 清理策略。表多时可用路由把多张表合并到少数主题,但要有取舍。

基本信息

命名topic.prefix + 库名 + 表名,可用路由规则改写
消息 key表主键:同键消息落到同一分区,保证单键有序
消息 value通常含 before、after、op、source 元数据(工具不同字段名略有差异)
分区数按峰值写入速率与下游并行度规划,避免频繁扩容
清理策略日志型用 delete;需要保留每键最新值的场景评估 compact
表范围先做白名单收敛,再规划分区与容量

典型使用场景

  • 新链路设计:确定主题命名、分区数与清理策略后再创建
  • 大库接入:表数量多时用路由把同域表合并到少数主题
  • 状态同步:需要每键最新值的镜像表场景,评估 compact
  • 顺序性要求高的场景:确认 key 为主键,避免同一单据乱序
  • 容量规划:按峰值写入与下游消费并行度确定分区数

主题与消息结构示意

主题与消息结构示意
# 主题命名:前缀 + 库 + 表
topic: cdc.app.orders

# 分区与顺序:同一主键固定落到同一分区,单键内有序
  key       = order_id
  partition = hash(key) % partitions

# 消息内容:变更前后镜像 + 操作类型 + 源端元数据
  value     = { before, after, op, source }

创建与核对

创建与核对
# 先按峰值吞吐估算分区数,再创建主题
kafka-topics.sh --bootstrap-server kafka1:9092 --create \
  --topic cdc.app.orders --partitions 12 --replication-factor 3 \
  --config retention.ms=604800000

# 核对分区与清理策略是否符合设计
kafka-topics.sh --bootstrap-server kafka1:9092 --describe --topic cdc.app.orders

设计选择对照

选择好处代价
一表一主题权限与消费隔离清晰,重放粒度细表多时主题数量膨胀,运维成本上升
多表路由合并主题数量可控,消费逻辑集中下游需按表名分发,权限难以按表细化
key 取主键同键有序,便于按主键去重与合并主键分布不均时分区倾斜
compact 策略保留每键最新值,读取即得当前状态丢失历史变更,无法回放中间过程
大库全表同步会产生大量小主题:先用白名单收敛范围,再规划分区与容量,不要一上手就按整库铺开,否则运维成本与存储都会失控。
分区数定小容易、改大代价高:扩容分区会改变键到分区的映射,破坏既有的分区内有序与下游按分区处理的前提,宁可前期多算一点。

易错点

  • 按库单主题混放多表,下游解析复杂且主键有序性被稀释
  • 分区数估算过小,业务高峰时单分区成为吞吐瓶颈,扩容又打乱键分布
  • key 留空或使用随机值,同一单据的变更分散到不同分区,下游顺序错乱
  • 变更流用 compact,历史变更被压实掉,需要重放时无数据可用
  • 主题不做保留期规划,磁盘占用随业务量增长无人治理

数据来源与参考

  • Debezium 官方文档(Topic naming 与 routing)
  • Kafka 官方文档(Topic compaction)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌