Debezium 性能优化
Debezium 的性能瓶颈 80% 不在 Debezium 本身,而在 数据库日志 -> Snapshot -> Kafka -> 下游消费 这条链路的协同配置。
DB 写入
↓
WAL / binlog 生成 ← DB 性能
↓
Debezium 解析日志 ← Connector 配置
↓
Kafka 写入 ← Kafka 吞吐
↓
Consumer 处理 ← 下游系统
任何一环慢,都会“看起来像 Debezium 慢”
✅ 表必须有 Primary Key
- 没主键:
- update / delete 需要全表 before image
- WAL 体积暴涨
- Debezium 解析慢
👉 性能 + 正确性双杀
✅ 合理设置 WAL 参数
wal_level = logical
max_replication_slots = 足够大
max_wal_senders = >= Debezium 数量
⚠️ 控制 WAL 生成量
- 避免:
- 大事务(一次更新百万行)
- 无谓的 UPDATE(值没变也 update)
👉 WAL 越大,Debezium 越慢
- Debezium 停止
- Slot 不消费
- WAL 无限增长
后果:
- IO 爆
- 磁盘满
- 数据库被拖死
👉 监控 replication slot 是生产必做项
- 全表扫描
- 大量事件
- Kafka 压力陡增
✅ 控制 snapshot 模式
snapshot.mode=initial | never | when_needed
- 已有数据同步过:
- 👉 never
- 新表上线:
- 👉 when_needed
✅ 并行 Snapshot(谨慎)
snapshot.fetch.size=2000
- 太大 -> DB 压力
- 太小 -> snapshot 慢
✅ 分表 snapshot(设计层面)
- 拆热点大表
- 历史表不做 CDC
max.batch.size=2048
max.queue.size=8192
poll.interval.ms=100
含义:
- max.batch.size:一次发送多少事件
- max.queue.size:内存缓冲
- poll.interval.ms:拉取频率
👉 吞吐 vs 内存 的权衡
✅ 只同步必要表
table.include.list=public.users,public.orders
✅ 只同步必要字段
column.include.list=public.users.id,public.users.name
👉 WAL 不变,但 Kafka / 网络 / Consumer 压力骤减
include.schema.changes=false
tombstones.on.delete=false
- Debezium 默认:
- 1 表 -> 1 topic
- 单 topic 吞吐不够:
- 增加分区数
⚠️ 前提:
- key 是主键
- 能接受乱序(跨 key)
producer.linger.ms=10
producer.batch.size=65536
producer.compression.type=lz4
👉 吞吐提升明显
transforms=unwrap
transforms.unwrap.type=io.debezium.transforms.ExtractNewRecordState
效果:
// 原始
{ before, after, source, op }
// unwrap 后
{ id, name, updated_at }
👉 消息体积 ↓ 50%~80%
- Avro / Protobuf
- JSON 体积大、CPU 高
- upsert
- replace by primary key
poll 1000 条
bulk insert / bulk update
- Consumer 慢
- Kafka backlog
- Debezium 被反压
👉 看起来像 Debezium 慢,实际是 Consumer 慢
必看指标
- replication slot lag(PG)
- WAL 磁盘使用
- Kafka topic lag
- Connect task 状态
- Debezium queue 使用率
- ❌ 没主键
- ❌ 大事务 + CDC
- ❌ snapshot 期间全业务高峰
- ❌ 不限制表 / 字段
- ❌ slot 不监控
- ❌ Kafka 分区过少
Debezium 性能优化 = 减 WAL + 控 Snapshot + 降事件体积 + 保 Kafka 吞吐 + 防慢消费者