Flink CDC 通过 Checkpoint 机制、幂等性设计 和 事务一致性协议 保障数据同步的一致性。以下是具体实现方式和关键配置:
1. Checkpoint 机制(核心保障)
作用:定期保存同步状态(包括 Binlog 位置和全量快照进度),确保任务失败后能恢复并避免重复/丢失数据。
关键配置:
sql
-- 启用 Checkpoint(SQL 环境) SET 'execution.checkpointing.interval' = '30s'; -- 每30秒一次 SET 'execution.checkpointing.mode' = 'EXACTLY_ONCE'; -- DataStream API 环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.enableCheckpointing(30000, CheckpointingMode.EXACTLY_ONCE); env.getCheckpointConfig().setCheckpointStorage("hdfs:///checkpoints/");
原理:
-
全量阶段:Checkpoint 记录已同步的数据分块和 Binlog 位置。
-
增量阶段:Checkpoint 记录已处理的 Binlog 事件位点(如
binlog_offset
)。
2. 两阶段快照(全量 + 增量无缝切换)
Flink CDC 使用 增量快照算法(Incremental Snapshot)保证全量和增量阶段的一致性:
-
全量阶段:
-
将表数据分块(Chunk)读取,每个分块完成后记录 Binlog 位置。
-
若任务中断,恢复时从最后一个完整分块继续。
-
-
增量阶段:
-
全量完成后,从记录的 Binlog 位置开始监听变更。
-
通过全局一致性快照确保全量数据与增量变更无遗漏或重复。
-
配置参数:
sql
'scan.incremental.snapshot.enabled' = 'true' -- 启用增量快照(默认) 'scan.incremental.snapshot.chunk.size' = '8096' -- 分块大小
3. 幂等性写入(目标端保障)
场景:当 Flink 任务重启时,可能重复发送数据到目标系统(如 Kafka、数据库)。
解决方案:
-
Kafka:依赖 Kafka 的幂等生产者(
enable.idempotence=true
)。 -
JDBC 数据库:使用
UPSERT
代替INSERT
(如 PostgreSQL 的ON CONFLICT
语法):sql
CREATE TABLE jdbc_sink ( id INT PRIMARY KEY, name STRING ) WITH ( 'connector' = 'jdbc', 'url' = 'jdbc:postgresql://localhost:5432/mydb', 'table-name' = 'users', 'sink.upsert-materialize' = 'NONE', -- 启用 Upsert 模式 'sink.primary-key' = 'id' -- 指定主键 );
-
Hudi/Iceberg:利用数据湖的
MERGE INTO
能力。
4. 事务一致性(精确一次语义)
场景:确保每条数据在目标端被处理且仅处理一次。
实现方式:
-
Flink 两阶段提交(2PC):
-
与支持事务的目标系统(如 Kafka 0.11+、JDBC)集成。
-
在 Checkpoint 完成时提交事务。
-
配置示例:
sql
-- Kafka Sink 的精确一次配置 CREATE TABLE kafka_sink ( id INT, name STRING ) WITH ( 'connector' = 'kafka', 'topic' = 'users_topic', 'properties.bootstrap.servers' = 'localhost:9092', 'format' = 'json', 'sink.delivery-guarantee' = 'exactly-once', -- 启用精确一次 'transactional-id-prefix' = 'cdc-sync-' -- 事务ID前缀 );
5. 异常处理与监控
-
断点续传:依赖 Checkpoint 恢复状态,无需人工干预。
-
监控指标:
-
flink_cdc_source_latest_offset
:当前消费的 Binlog 位点。 -
flink_cdc_source_snapshot_rows
:全量阶段已同步行数。
-
-
错误恢复:
-
自动重试:通过 Flink 的重试策略处理临时错误。
-
死信队列:将失败数据写入侧输出流(Side Output)人工处理。
-
6. MySQL 端配置要求
确保 MySQL 满足以下条件:
-
Binlog 配置:
ini
[mysqld] log_bin=mysql-bin binlog_format=ROW -- 必须为 ROW 模式 binlog_row_image=FULL -- 记录完整行数据 server_id=1 -- 唯一ID expire_logs_days=7 -- Binlog 保留时间需大于同步延迟
-
用户权限:
sql
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'flink_user'@'%';
总结:一致性保障链条
-
源头:MySQL Binlog 提供有序变更事件。
-
采集端:Flink CDC 通过 Checkpoint 持久化状态。
-
处理端:幂等写入 + 事务机制。
-
目标端:支持 Upsert 或事务的存储系统。
通过以上机制,Flink CDC 可实现 端到端的精确一次(Exactly-Once)一致性。