Flink CDC 锁表原理详解

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

        Flink CDC 是一种基于 Apache Flink 和 Change Data Capture (CDC) 技能的数据同步工具,主要用于捕获数据库中的及时数据变动。在实现及时同步的过程中,Flink CDC 会涉及到 锁表 的利用,特殊是在全量同步阶段。这是为了保证数据同等性,尤其是处理全量和增量数据无缝衔接时的精确性。
        下面详细解释 Flink CDC 锁表的原理及每一步的利用,逐步分解技能细节,易于明白:

1. 什么是锁表?



  • 概念:锁表是指在数据库利用中,限定对某张表的读写权限,防止其他事务对表举行更新或修改。这样可以确保当前利用的数据不会被破坏。
  • 目的:在 Flink CDC 的全量数据导出时,锁表可以制止其他事务修改数据,确保导出的全量数据和随后的增量变动数据没有冲突,从而实现数据的同等性。

2. 为什么 Flink CDC 需要锁表?

Flink CDC 的工作分两部分:

  • 全量读取:将数据库当前的全部数据导出到 Flink。
  • 增量监听:捕获数据表中后续的全部新增、修改、删除利用。
        尽管数据库(如 MySQL)支持 MVCC 技能,通过同等性快照来读取数据,但以下题目可能导致全量与增量数据的不同等:
        (1) 防止数据遗漏或重复

在全量读取开始时,如果新的事务在写入数据库,而 Binlog 的起始位点未精确捕获,则会出现:


  • 遗漏题目:某些数据已经写入数据库,但未出现在全量数据中,也未出现在增量日记中。
  • 重复题目:某些数据可能同时出现在全量数据和增量日记中。
通过锁定表,可以保证全量数据读取时,表中的状态是静态的。
        (2) 防止 DDL 利用引起不同等

如果在全量读取时有 DDL 利用(如新增列、修改列),可能导致:


  • 全量读取的表结构与增量日记捕获的表结构不同等。
  • 读取数据时可能出现字段错位或分析错误。
锁表可以防止在读取时发生 DDL 利用。

因此,锁表是必要的,锁表可以确保:


  • 全量读取的数据在捕获完成前不会被其他事务修改。
  • 增量捕获的起点与全量读取的结束点无缝衔接。

3. Flink CDC 锁表的工作原理(详细分解)

(1)初始化任务



  • Flink CDC 启动后,起首毗连到目标数据库,确定需要同步的表。
  • 系统会记载一个全量任务开始时间点,这个时间点也用于后续增量捕获的起点。
(2)全量数据读取



  • Flink CDC 利用 SQL 查询提取表中的全部数据。例如:
    1. SELECT * FROM table_name;
    复制代码
  • 在读取的过程中,为了防止数据变革,Flink CDC 会实验加共享锁(读锁)
(3)加锁机制



  • 如何加锁?

    • 在 MySQL 数据库中,Flink CDC 利用 REPEATABLE READ 隔离级别或类似机制,确保读取的数据快照不会受到其他事务的更新影响。
    • 对于某些数据库(如 MySQL),会用到表锁机制(例如 LOCK TABLES 命令)。

  • 锁的范例:

    • 读锁(共享锁,S 锁):允许多个读取利用同时举行,但克制写入。
    • 在全量读取阶段,Flink CDC 会实验对目标表加读锁。

  • 锁表的影响:

    • 如果其他事务实验更新目标表,会被阻塞,直到 Flink CDC 完成读取并开释锁。
    • 如果表上已有写锁,则 Flink CDC 的全量任务可能会等待,直到写锁被开释。

(4)记载增量起点



  • 在全量读取完成后,Flink CDC 会记载当前时间点或 binlog 日记位置(例如 MySQL 的 binlog 文件和偏移量)。
  • 这确保后续的增量捕获可以从这个位置开始,无缝衔接全量数据。
(5)开释锁



  • 全量数据读取完成后,Flink CDC 会立即开释表锁,让其他事务规复正常利用。
  • 锁的开释时间通常很短,因为全量读取利用主要是次序扫描,不会涉及复杂事务。
(6)开始增量捕获



  • 锁表结束后,Flink CDC 切换到增量模式,通过监听数据库日记(如 MySQL 的 binlog)来捕获数据的变动。
  • 通过之前记载的起点位置(全量结束点),Flink CDC 确保增量变动与全量读取的数据不会重复或遗漏。


Flink CDC 的底层原理

        Flink CDC 的实现原理基于 MySQL 的同等性快照(Consistent Snapshot)和 Binlog 捕获,详细如下:
3.1 同等性快照

MySQL 利用 MVCC(多版本并发控制) 和事务隔离级别来支持同等性快照读取:


  • Flink CDC 通过实行 START TRANSACTION WITH CONSISTENT SNAPSHOT 来获取当前时间点的数据库状态。
  • 这使得全量读取时,数据只会反映事务开始时的状态,而不受后续写利用影响。
  • 同等性快照通过 REPEATABLE READ 隔离级别实现,利用 Undo Log 保证读取的是事务开始时的数据版本。
   通俗明白:MySQL 会记载每一行数据的多个历史版本,快照全量读取就像拍了一张静态照片,无论后续有多少数据写入,这张照片始终不变。
  

  • 全量读取:就像拍摄一张照片,确保照片中的内容完备同等。
    锁表是为了防止有人在照相时移动或改变物品。
  • 增量捕获:在拍完照片后,开始记载物品的每一次移动或变革。
    起点位置是照相的时间点。
  3.2 记载 Binlog 位点

在全量读取开始时,Flink CDC 会通过以下方式记载 Binlog 的起始位点:


  • 获取当前 MySQL 的 Binlog 文件名及偏移量(Position)。
  • 这些信息用于后续增量数据捕获的起始点。
通过记载位点,可以保证增量读取从全量读取结束后精准地衔接起来。
3.3 锁表利用

在某些情况下,Flink CDC 会显式加锁以保证全量和增量读取的同等性,主要包罗:

  • 防止 DDL 利用:通过 LOCK TABLES 或其他显式加锁手段,制止全量读取期间表结构发生变动。
  • 无法利用 MVCC 的场景:如果数据库或表不支持同等性快照,可能需要加表锁,防止其他事务写入。

4. 总结 Flink CDC 锁表的流程


  • 启动全量读取任务:加共享锁,防止数据在读取时被修改。
  • 读取全量数据:实行查询,次序扫描表中的数据。
  • 记载增量起点:确定日记位置或时间点,为增量捕获做准备。
  • 开释锁:全量任务完成后立即开释表锁。
  • 启动增量捕获任务:监听日记,处理表中的后续数据变动。
全量数据读取阶段


  • 启动事务

    • Flink CDC 会在读取全量数据前启动一个快照读取事务。
    • 通过 START TRANSACTION WITH CONSISTENT SNAPSHOT 命令,保证读取的全量数据基于同等的快照。

  • 记载 binlog 位点

    • Flink CDC 在开始读取全量数据时,记载当前的 binlog 位点(Log Sequence Number, LSN)。
    • 此位点作为增量读取的起始点。

  • 读取全量数据

    • 利用同等性快照的方式,制止因表数据更新导致全量读取的不同等。

增量数据读取阶段



  • 全量数据读取完成后,Flink CDC 开始从上述记载的 binlog 位点捕获增量数据。
  • 此时不再需要锁表。

5. 源代码分析

        以 Flink CDC 的 MySQL Connector 为例,其核心流程主要在以下模块中实现:
5.1 全量读取阶段



  • 代码入口:MySqlSnapshotSplitReader.java
  • 关键方法
    1. public void readSplit(MySqlSnapshotSplit split) {
    2.     // 1. 开启事务,获取一致性快照
    3.     statement.execute("START TRANSACTION WITH CONSISTENT SNAPSHOT");
    4.     // 2. 记录 Binlog 起始位置
    5.     binlogOffset = fetchCurrentBinlogPosition();
    6.     // 3. 读取全量数据
    7.     resultSet = executeTableScanQuery(split.getTable());
    8. }
    复制代码
解释


  • START TRANSACTION WITH CONSISTENT SNAPSHOT 开启同等性快照。
  • fetchCurrentBinlogPosition 获取当前 Binlog 位点,记载增量读取的起点。
  • 表扫描基于快照读取,保证全量数据同等。
5.2 增量读取阶段



  • 代码入口:MySqlSourceReader.java
  • 关键方法
    1. public void fetchBinlogData(BinlogOffset startOffset) {
    2.     // 使用 Binlog Client 从指定位置开始捕获增量数据
    3.     binlogClient.connect(startOffset);
    4. }
    复制代码
解释


  • 增量数据捕获从全量读取时记载的 Binlog 位点开始。
  • Binlog 捕获及时变动利用,并分析成 Flink 可处理的事件流。
5.3 锁表相关逻辑



  • 代码位置:MySqlSnapshotSplitAssigner.java
  • 关键方法
    1. public void lockTable(String tableName) {
    2.     statement.execute("LOCK TABLES " + tableName + " READ");
    3. }
    复制代码
解释


  • LOCK TABLES 用于显式锁定表,防止 DDL 利用或写入。
  • 通常在读取前手动加锁,读取完成后开释。

6. 锁表对系统的影响



  • 性能影响

    • 锁表会阻塞写利用,可能导致其他业务事务出现短暂延迟。
    • 对于高并发业务环境,建议在业务低峰期举行全量同步。

  • 优化建议

    • 利用主从数据库同步:在从库实行全量同步,制止影响主库的读写性能。
    • 限定全量同步的速率:低落读取速率,淘汰对数据库资源的占用。
    • 利用 MVCC:大多数情况下,Flink CDC 通过同等性快照(MVCC)制止显式锁表。
    • 短期加锁:仅在切换点记载时短时间锁定表。
    • 优化配置:通过参数设置制止不必要的锁表利用。


7. 总结

        Flink CDC 的锁表原理主要是通过短时间加读锁,保证全量读取数据的同等性,并团结增量日记捕获机制,实现无缝的数据同步。锁表时间通常很短,但在高并发环境中,仍需注意对性能的影响,合理规划同步任务的实行时间和策略。
        整个过程依赖数据库的 MVCC 和 Binlog 功能,团结 Flink 的分布式处理能力,实现了及时同等的数据捕获和处理。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表