在分布式/微服务架构中,订单、用户、库存、支付等数据往往分散在不同的业务数据库里(如 MySQL、PostgreSQL、MongoDB、Redis)。要做综合报表、数据中台、实时画像、离线数仓或下游同步(缓存、搜索、ES、Lakehouse),就需要无侵入、低耦合地感知上游库表的数据变化。本文系统整理四类数据库的变更感知手段与工程化落地要点,覆盖你给出的全部知识点并做必要扩展。


1. 为什么要做“数据变化感知”(CDC)

  • 系统解耦:业务服务各自写自己的库;由 CDC 把变化异步分发到下游(数仓、ES、缓存、画像、指标)。
  • 无侵入:不改业务代码,不在每次写入时手动“顺带写数据仓库”。
  • 实时性:毫秒/秒级将新增、更新、删除事件传播出去。
  • 一致性与可追溯:从数据库原生日志或机制中“重放事实”,天然具备顺序与事务上下文(视库而定)。

常见实现思路:监听数据库的变更日志或通知机制 → 解析为结构化事件(INSERT/UPDATE/DELETE)→ 投递至消息总线/下游系统;必要时再配合快照补齐校对实现全量+增量一致。


2. MySQL:基于 Binlog 的 CDC(两种格式 + 混合模式)

核心机制:Binlog 二进制日志

  • 记录“做过什么”,供主从复制、恢复、CDC 使用。
  • 三种格式:
    1. SBR(Statement-Based Replication):记录 SQL 语句本身(做了什么)。
    2. RBR(Row-Based Replication):记录行级变化前/后镜像(变成了什么)。
    3. 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 基础流程(全量 + 增量)

  1. 全量快照:初始化把当前数据拉平到下游(数据湖/数仓/索引/缓存)。
  2. 增量订阅:从 Binlog/WAL/Change Streams/Keyspace 接入变化事件。
  3. 断点续传:记录位点(MySQL 文件名+偏移/GTID、PostgreSQL LSN、Mongo resume token)。
  4. 回放与校对:处理失败/重放、定期与上游对账(尤其 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 ConnectKafka 主题
  • 下游多订阅方(实时计算、检索、缓存、数仓离线)各取所需;
  • 统一位点、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 BinlogPostgreSQL WAL 是关系型数据库 CDC 的金标准;
  • MongoDB Change Streams 以官方封装降低了门槛;
  • Redis Keyspace 适合缓存侧联动,非强 CDC。

把 CDC 做成平台化能力(连接器 + 总线 + 位点治理 + Schema 管理 + 可观测性),就能在不侵入业务的前提下,把多源数据“流”起来,为实时数仓、画像、搜索与风控提供稳定、低延迟的事实底座。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐