Debezium Incremental分析

简介

Incremental snapshotting提供了任意时间点可触发的快照同步、可中断恢复的快照、与流模式并行的快照,也提供了捕获新表快照的能力。

Debezium官方对增量快照设计解释
Netflix DBLog论文

配置使用

  • 正常开启Source端抽取,只开启流模式,没有进行历史数据同步。且配置signal.data.collection信号表,表结构如下
# 表名随意 只需要跟signal.data.collection的值对应起来即可 为schema.table模式的名字
CREATE TABLE debezium_signal (id VARCHAR(42) PRIMARY KEY, type VARCHAR(32) NOT NULL, data VARCHAR(2048) NULL);
  • 一定要保证signal.data.collection配置的表 要被流模式捕获!oracle需要配置为database.schema.table格式
  • 此时我们如果要触发某一张表或者某一批表的历史数据快照,我们只需要往debezium_signal表里插入
# id随意取名 但建议命名可读
INSERT INTO public.debezium_signal (id, type, data) VALUES('ad-hoc-1', 'execute-snapshot', '{"data-collections":["public.config"]');
  • 此时Dbz就是public.config这样表开启了增量快照同步

原理分析

基本流程图

image

时序图

image

处理数据示例

image

DBZ代码流程分析

基本流程

  • io.debezium.pipeline.EventDispatcher#dispatchDataChangeEvent

  • io.debezium.pipeline.spi.ChangeRecordEmitter#emitChangeRecords

  • io.debezium.pipeline.spi.ChangeRecordEmitter.Receiver#changeRecord

  • io.debezium.pipeline.signal.ExecuteSnapshot#arrived

  • 插入新表的增量快照触发
    image
    image

  • 然后会触发进入第一次的read chunk 然后会调用

  • io.debezium.pipeline.source.snapshot.incremental.AbstractIncrementalSnapshotChangeEventSource#emitWindowOpen 方法往信号表里插入一条开启窗口的语句

  • 然后会根据排序规则 取到 当前主键组合最大的值 然后进行 Select数据 当一批数据库Select完成之后

  • 读取到的数据会被写入到下述变量之中io.debezium.pipeline.source.snapshot.incremental.AbstractIncrementalSnapshotChangeEventSource#window

  • 然后调用io.debezium.pipeline.source.snapshot.incremental.AbstractIncrementalSnapshotChangeEventSource#emitWindowClose 方法往信号表里插入一条关闭窗口的语句

  • 上述整个过程 会阻挡Stream读取一小会时间

  • 关闭窗口之后 会继续处理Stream的消息

  • 当处理到上面 发送的窗口打开消息的时候 调用下面方法 标记window已经打开

  • io.debezium.pipeline.source.snapshot.incremental.OpenIncrementalSnapshotWindow#arrived

  • 然后接着处理Stream的消息,但是会对每条消息跟Window缓存的消息对比,如果发现有更新就保留流式消息最后的结果
    image
    image

  • 当Stream消息读取到Close window的时候,会触发io.debezium.pipeline.source.snapshot.incremental.CloseIncrementalSnapshotWindow#arrived

  • 然后会将消息发送到Kafka 完成一次窗口数据的读取合并与发送。

QA

为什么说增量快照是可恢复的

基于信号表的窗口开启关闭与kafka connect offset机制,可以实现当Connect重启之后,重新读取快照的消息。Offset在增量快照阶段,会储存incremental_snapshot_collections、incremental_snapshot_primary_key、incremental_snapshot_maximum_key三个字段来记录增量快照的进程。当出现故障重启的的时候,会读取Offset的内容进行原位置恢复。io.debezium.pipeline.source.snapshot.incremental.AbstractIncrementalSnapshotContext#store

为什么说任意时间点可触发的快照同步

通过Signal表与流阶段捕获消息的方式,可以在任意时间节点,往信号表里插入触发某些表增量同步的信号。

posted @ 2022-03-28 17:17  meetzy  阅读(704)  评论(0编辑  收藏  举报