4. 数据采集与同步技术:全量同步、增量同步、CDC机制、实时流式采集
数据采集是数据共享平台的“入口”。你想想看,数据进不来,后面再牛的分析、治理都是空谈。这一章,我带你把这四种采集方式彻底搞明白。
核心观点:没有万能的采集方案。全量、增量、CDC、实时流式,各有各的适用场景。选错了,轻则浪费资源,重则数据不一致,甚至影响业务。
4.1 全量同步:最“笨”但最可靠的方法
全量同步,说白了就是把源表的数据全部复制一份到目标端。每次跑都是“清空-重写”。
什么时候用?
- 第一次搭建数据平台,需要把历史数据全部拉过来。
- 数据量小(百万级以内),跑一次几分钟搞定。
- 源表没有合适的增量字段,或者业务允许短时间锁表。
我的经验:全量同步虽然简单,但坑也不少。我曾经遇到一个项目,每天全量同步一张千万级的大表,结果跑了一个多小时,把源库的IO打满了,业务直接报警。后来我改成增量同步,问题才解决。
全量同步的典型实现:
-- 示例:MySQL 全量导出到 Hive
-- 步骤1:从 MySQL 导出
mysqldump -h source_host -u user -p db_name table_name > /tmp/table_name.sql
-- 步骤2:导入到 Hive(先清空目标表)
TRUNCATE TABLE target_db.table_name;
LOAD DATA LOCAL INPATH '/tmp/table_name.csv' OVERWRITE INTO TABLE target_db.table_name;
4.2 增量同步:只取“新”和“变”
增量同步只处理新增或修改的数据。相比全量,它更轻量,对源库的压力也小得多。
常见的增量字段策略:
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 时间戳 | 记录最后修改时间,每次取 > 上次时间的数据 | 实现简单 | 依赖业务更新时间准确;无法捕获删除 |
| 自增ID | 记录最大ID,每次取 > 上次ID的数据 | 性能好,无时间偏差 | 只能处理新增,无法处理修改 |
| 版本号 | 每行记录一个版本号,递增 | 可处理修改 | 业务改造大,不通用 |
注意:时间戳策略有个经典坑——时钟回拨。如果源库服务器时间被调整,或者跨时区,增量数据可能漏掉或重复。我曾经在跨机房同步时吃过这个亏,后来统一用NTP服务才解决。
4.3 CDC 机制:真正的“变化捕获”
CDC(Change Data Capture)不是简单的增量同步。它监听数据库的变更日志,捕获每一行数据的插入、更新、删除操作。
CDC 的两种主流实现:
- 基于日志解析:解析 MySQL binlog、PostgreSQL WAL、Oracle Redo Log。性能好,对源库无侵入。
- 基于触发器:在源表上创建触发器,将变更写入一张变更表。实现简单,但会降低源库写入性能。
我个人更推荐日志解析方式。为什么?因为它不改变业务代码,也不影响源库的正常写入。我在一个金融项目中,用 Debezium 解析 MySQL binlog,实时同步到 Kafka,延迟控制在 100ms 以内。
-- 示例:开启 MySQL binlog(my.cnf 配置)
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW -- 必须使用 ROW 格式
expire_logs_days = 7
关键点:CDC 能捕获删除操作,这是时间戳增量做不到的。如果你的数据共享平台需要保证源端和目标端完全一致,CDC 是首选。
4.4 实时流式采集:毫秒级响应
实时流式采集是 CDC 的“升级版”。它把数据变更变成一个个事件,通过消息队列(如 Kafka)实时推送给下游。
典型的实时流式架构:
- 源数据库产生变更(binlog)。
- CDC 工具(如 Debezium、Canal)捕获变更,转为事件。
- 事件发送到 Kafka Topic。
- Flink/Spark Streaming 消费事件,做 ETL 或直接写入目标。
为什么需要流式?你想想看,如果业务要求数据延迟不超过 1 秒,增量同步(分钟级)和 CDC(秒级)都做不到。只有流式架构,才能把延迟压到毫秒级。
避坑指南:我曾经在一个项目中,直接用 Flink 消费 Kafka 的 CDC 事件,然后写入 HBase。结果遇到 Kafka 分区数据倾斜,某个分区积压了几百万条事件,导致实时性完全失效。后来我加了数据重分区和背压监控,才稳住。
4.5 四种方式对比与选型
| 特性 | 全量同步 | 增量同步 | CDC | 实时流式 |
|---|---|---|---|---|
| 数据延迟 | 小时级 | 分钟级 | 秒级 | 毫秒级 |
| 源库压力 | 高 | 低 | 极低 | 极低 |
| 捕获删除 | 支持(全量覆盖) | 不支持 | 支持 | 支持 |
| 实现复杂度 | 低 | 中 | 高 | 很高 |
| 适用场景 | 首次加载、小表 | 低频变化表 | 高一致要求 | 实时数仓、风控 |
我的选型建议:
- 第一次建平台,先用全量把历史数据拉过来。
- 日常同步,优先用增量(时间戳或自增ID)。
- 如果业务要求源和目标完全一致(包括删除),上 CDC。
- 如果延迟要求 < 1 秒,别犹豫,直接上实时流式。
最后提醒一句:不要为了“炫技”而用实时流式。实时流式的运维成本很高,Kafka、Flink、CDC 工具,任何一个环节出问题,排查起来都很痛苦。能用增量解决的,就别上 CDC;能用 CDC 解决的,就别上流式。