四大主流数据库的数据变更感知(CDC)实战指南:MySQL、PostgreSQL、MongoDB、Redis
本文系统介绍了分布式架构中四种数据库(MySQL、PostgreSQL、Redis、MongoDB)的数据变更感知(CDC)实现方案。MySQL基于Binlog的RBR模式,PostgreSQL通过WAL逻辑复制槽,MongoDB使用官方Change Streams,Redis则依赖有限的Keyspace通知功能。文章详细对比了各方案优缺点,并提出了通用工程化实践,包括全量+增量同步、断点续传、事
在分布式/微服务架构中,订单、用户、库存、支付等数据往往分散在不同的业务数据库里(如 MySQL、PostgreSQL、MongoDB、Redis)。要做综合报表、数据中台、实时画像、离线数仓或下游同步(缓存、搜索、ES、Lakehouse),就需要无侵入、低耦合地感知上游库表的数据变化。本文系统整理四类数据库的变更感知手段与工程化落地要点,覆盖你给出的全部知识点并做必要扩展。
1. 为什么要做“数据变化感知”(CDC)
- 系统解耦:业务服务各自写自己的库;由 CDC 把变化异步分发到下游(数仓、ES、缓存、画像、指标)。
- 无侵入:不改业务代码,不在每次写入时手动“顺带写数据仓库”。
- 实时性:毫秒/秒级将新增、更新、删除事件传播出去。
- 一致性与可追溯:从数据库原生日志或机制中“重放事实”,天然具备顺序与事务上下文(视库而定)。
常见实现思路:监听数据库的变更日志或通知机制 → 解析为结构化事件(INSERT/UPDATE/DELETE)→ 投递至消息总线/下游系统;必要时再配合快照补齐与校对实现全量+增量一致。
2. MySQL:基于 Binlog 的 CDC(两种格式 + 混合模式)
核心机制:Binlog 二进制日志
- 记录“做过什么”,供主从复制、恢复、CDC 使用。
- 三种格式:
- SBR(Statement-Based Replication):记录 SQL 语句本身(做了什么)。
- RBR(Row-Based Replication):记录行级变化前/后镜像(变成了什么)。
- Mixed:按场景在 SBR 与 RBR 间切换。
工程建议
- CDC 场景下更常用 RBR 或 Mixed,因为行级事件更稳定、可重放性强、歧义少。
- 结合 GTID 与从库位点/文件名跟踪,保证断点续传。
- 常用工具:Flink CDC、Debezium 等直接消费 Binlog,解析出标准化数据变更事件,再写 Kafka、Pulsar、ES、Iceberg/Hudi/Delta 等。
优缺点
- 优:生态成熟、资料丰富、延迟低。
- 缺:DDL 变更处理复杂;跨表事务需注意顺序;大事务可能造成消费端延迟抖动。
3. PostgreSQL:基于 WAL 的 CDC(预写日志)
核心机制:WAL(Write-Ahead Logging)
- 与 Binlog 类似,先写日志再落数据。
- WAL 被切分成多个日志段,持久化在
pg_wal目录。每段包含多页;页内记录事务时间戳、LSN(位置序号)、事务标识、变更内容等。
CDC 获取方式
- 建议使用 逻辑复制(Logical Decoding):为库/表创建复制槽(Replication Slot),消费逻辑变更流。
- 解析插件可用
pgoutput(内置)或第三方(wal2json、decoderbufs)。 - 上层依旧可用 Flink CDC / Debezium 对接 WAL(逻辑解码输出),实现断点续传与标准化事件。
优缺点
- 优:原生复制语义清晰;逻辑复制配合复制槽天然定位断点。
- 缺:复制槽管理需要运维规范;DDL 兼容视插件能力而定;长时间积压可能膨胀 WAL。
4. Redis:Keyspace Notifications(变更通知)与其局限
核心机制:Keyspace Notifications
- 基于 Redis 的发布/订阅,订阅特殊频道(如
__keyevent@0__:*)即可收到 键事件:新增、更新、删除、过期等。 - 适合监听缓存层面的变化,如感知某 Key 的失效来做二级缓存回填或清理。
重要局限
- Fire-and-forget:连接在、网络通畅时才能收到通知;连接断开/抖动期间的事件不会重发。
- 因此不适合用作强一致 CDC,只能作为辅助信号。
- 如果需要更可靠的流式消费,可考虑 Redis Streams(仍非数据库 CDC 的严格替代品)或把 Redis 当缓存,由源库 CDC作为权威数据流。
工程建议
- 对价值不大的变化(如缓存重建、热点淘汰)可用 Keyspace 事件。
- 对关键数据务必配合定期校对或快照比对,或以 MySQL/PostgreSQL 的 CDC 为准,再驱动 Redis 同步。
5. MongoDB:Oplog 与 Change Streams(官方推荐)
核心机制
- 底层有 Oplog(operation log) 记录副本集内的变更。
- MongoDB 官方在 Oplog 之上提供了 Change Streams:
- 应用建立长连接订阅库/集合/聚合管道的变更;
- 由 MongoDB 主动推送变化事件(插入、更新、替换、删除等);
- 免去手工解析 Oplog 的繁琐与坑点,是业务开发的首选入口。
工程建议
- 直接使用驱动的 Change Streams API;
- 生产环境务必启用 副本集(Change Streams 依赖);
- 合理设置 resume token、心跳与重连策略。
6. 共通工程化实践(适用于四类数据库)
6.1 基础流程(全量 + 增量)
- 全量快照:初始化把当前数据拉平到下游(数据湖/数仓/索引/缓存)。
- 增量订阅:从 Binlog/WAL/Change Streams/Keyspace 接入变化事件。
- 断点续传:记录位点(MySQL 文件名+偏移/GTID、PostgreSQL LSN、Mongo resume token)。
- 回放与校对:处理失败/重放、定期与上游对账(尤其 Redis)。
6.2 事件语义与幂等
- 至少一次是常态,必须幂等:下游根据主键/版本号/变更时间戳去重。
- 顺序性:按主键路由(Kafka 分区键/任务分片),保证同一实体内事件顺序。
- 大事务:拆分/批处理,设置合理的内存与缓冲;对长时间未提交的事务要告警。
6.3 DDL 与模式演进
- DDL 事件要么同步到下游(自动建表/扩列),要么与业务约定“只追加字段”。
- 使用 Schema Registry 或元数据服务管理字段变更(JSON/Avro/Protobuf)。
- 避免破坏性改名;必要时做字段映射层。
6.4 时区/时间与精度
- 统一时区(UTC);
- 统一时间戳精度(毫秒/纳秒);
- 写入下游时保留“发生时间”和“入湖时间”。
6.5 回压与容错
- 配置消费速率、批量大小、重试与死信队列(DLQ);
- 监控滞后量、延迟、错误类型、重放次数;
- 重要链路具备审计与回放工具。
6.6 安全与审计
- 只授予 CDC 所需的最小权限(只读复制权限、逻辑复制权限);
- 敏感字段做脱敏/加密;
- 记录谁在消费、消费到哪儿、故障分析流水。
7. 实施参考方案
7.1 以 Flink CDC 为中心的实时链路
- MySQL:RBR/Mixed Binlog → Flink CDC Source → 解析 → 下游(Kafka/ES/对象存储/湖仓)。
- PostgreSQL:逻辑复制槽(pgoutput)→ Flink CDC Source → 下游。
- MongoDB:Change Streams → Flink CDC Source → 下游。
- Redis:仅作为缓存层;由上游权威 CDC 同步最终结果到 Redis,Keyspace 仅作局部联动。
7.2 以 Debezium 为中心的总线化架构
- 连接器(MySQL/PostgreSQL/MongoDB)→ Kafka Connect → Kafka 主题;
- 下游多订阅方(实时计算、检索、缓存、数仓离线)各取所需;
- 统一位点、Schema、告警、回放工具由 Kafka 侧承接。
8. 对比与选型建议
| 数据库 | 官方/原生能力 | 推荐 CDC 入口 | 可靠性 | 复杂度 | 典型用途 |
|---|---|---|---|---|---|
| MySQL | Binlog(SBR/RBR/Mixed) | RBR/Mixed + Flink CDC/Debezium | 高 | 中 | 交易库、订单库 |
| PostgreSQL | WAL + 逻辑复制槽 | pgoutput + Flink CDC/Debezium | 高 | 中 | 核心账务、画像 |
| MongoDB | Oplog → Change Streams | 官方 Change Streams | 高 | 低 | 文档存储、事件推送 |
| Redis | Keyspace Notifications | 事件通知(非强 CDC) | 低 | 低 | 缓存联动、二级缓存 |
结论
- 权威数据源(关系型/文档型)用 Binlog/WAL/Change Streams 做 CDC;
- Redis 更适合当缓存的“响应式联动”,不要指望其提供强一致 CDC;
- 工程上统一以 消息总线 + Schema 管理 + 位点治理 做平台化沉淀。
9. 最小示例(思路级伪代码)
9.1 MySQL(Flink CDC)
MySqlSource<String> source = MySqlSource.<String>builder()
.hostname("mysql")
.username("cdc_user")
.password("******")
.databaseList("biz_db")
.tableList("biz_db.orders")
.serverTimeZone("UTC")
.deserializer(new JsonDebeziumDeserializationSchema())
.build();
9.2 PostgreSQL(逻辑复制)
PostgreSQLSource<String> source = PostgreSQLSource.<String>builder()
.hostname("pg")
.database("biz")
.slotName("cdc_orders_slot")
.pluginName("pgoutput")
.deserializer(new JsonDebeziumDeserializationSchema())
.build();
9.3 MongoDB(Change Streams)
MongoClient client = MongoClients.create(uri);
MongoCollection<Document> col = client.getDatabase("biz").getCollection("orders");
col.watch().forEach(change -> handle(change)); // 直接收变更事件
9.4 Redis(Keyspace)
notify-keyspace-events Ex # 启用过期/事件通知
SUBSCRIBE "__keyevent@0__:expired" "__keyevent@0__:del"
仅作缓存联动,关键链路请依赖权威 CDC。
10. 落地清单(Checklist)
- 明确全量+增量策略与位点落盘规则
- 统一 Schema 与字段演进规范(禁止破坏性变更)
- 幂等、顺序、去重策略到位
- DDL 处理方案与告警
- 大事务与积压的观测与熔断
- 权限最小化、敏感数据脱敏
- 回放/补数工具、数据对账机制
- Redis 仅作补充性通知,关键数据以权威源为准
结语
- MySQL Binlog 与 PostgreSQL WAL 是关系型数据库 CDC 的金标准;
- MongoDB Change Streams 以官方封装降低了门槛;
- Redis Keyspace 适合缓存侧联动,非强 CDC。
把 CDC 做成平台化能力(连接器 + 总线 + 位点治理 + Schema 管理 + 可观测性),就能在不侵入业务的前提下,把多源数据“流”起来,为实时数仓、画像、搜索与风控提供稳定、低延迟的事实底座。
更多推荐
所有评论(0)