在这篇文章中,我们将深入探讨 Debezium 2.0 中的所有变化,讨论新功能并解释所有可能在升级过程中产生影响的重大变化。一如既往,我们强烈建议您查看发行说明,以了解有关所有已修复错误、更新程序等的更多信息。[发行说明],尤其是从旧版本升级时。
Debezium 的基本核心在 Debezium 2.0 中发生了很大变化。在本节中,我们将深入探讨 Debezium 核心的变化,并讨论这些变化如何影响 Debezium 的所有用户。
很长一段时间以来,我们一直想实现 Java 11 的飞跃,我们认为 Debezium 2.0 是正确的时机。使用 Java 11,这使我们能够利用新的语言特性,例如新的StringAPI 和Predicate代码库中的支持更改,同时还受益于许多 Java 性能改进。
从 Debezium 2.0 的第一个版本 2.0.0.Alpha1 开始, Debezium 位将被编译为 Java 11 字节代码。因此,在下一次重大更新中将需要 Java 11 才能运行 Debezium。此外,如果您在项目中使用任何 Debezium 位作为库(使用 Debezium嵌入式引擎),则必须切换到 Java 11。
停止
自从我们首次引入增量快照以来,用户一直在寻求一种方法来停止正在进行的快照。为此,我们添加了一个新信号 ,stop-snapshot它允许停止正在进行的增量快照。该信号将像其他任何信号一样发送,方法是在信号表/集合中插入一行,如下所示:
INSERT INTO schema.signal_table (id, type,data)
VALUES ('unique-id', 'stop-snapshot', '_<signal payload>_`);
stop-snapshot有效载荷看起来与其对应物非常相似execute-snapshot。一个例子:
{
"data-collections": ["schema1.table1", "schema2.table2"],
"type": "incremental"
}
此示例从增量快照中删除schema1.table1和schema2.table2,只要表或集合尚未完成其增量快照。如果在删除指定的表或集合后其他表或集合仍然未完成data-collections,则增量快照将继续处理那些未完成的。如果没有其他表或集合剩余,则增量快照将停止。
另一个stop-snapshot有效载荷的例子非常简单:
{
"type": "incremental"
}
此示例未指定data-collections属性,它对于stop-snapshot信号是可选的。如果未指定此属性,则该信号表示应完全停止当前正在进行的增量快照。这提供了在不知道当前或尚未捕获的表或集合的情况下停止增量快照的能力。
暂停和恢复
增量快照已成为 Debezium 中不可或缺的功能。增量快照功能允许用户出于各种原因在一个或多个集合/表上重新运行快照。增量快照最初只是通过一个开始信号引入的。我们最终添加了停止正在进行的增量快照或能够从正在进行的增量快照中删除集合/表子集的功能。
在此版本中,我们建立在现有信号基础之上,并引入了两个新信号,一个用于暂停正在进行的增量快照,另一个用于恢复先前已暂停的增量快照。要暂停增量快照,pause-snapshot必须发送一个信号,要恢复,resume-snapshot可以使用一个信号。
这两个新信号可以使用信号表策略或 MySQL 的 Kafka 信号主题策略发送。有关信号及其工作原理的更多详细信息,请参阅信号支持文档。
使用正则表达式
增量快照信号要求在data-collections有效负载属性中使用显式表/集合名称。虽然这很有效,但在某些情况下,广泛的捕获配置可能会利用正则表达式的使用。我们已经在连接器配置选项中支持正则表达式,例如包含/排除列表,因此将其扩展到增量快照也很有意义。
从 Debezium 2.0 开始,所有增量快照信号都可以在data-collectionspayload 属性中使用正则表达式。使用上面的停止信号示例之一,可以使用正则表达式重写有效负载:
{
"data-collections": ["schema[1|2].table[1|2]"],
"type": "incremental"
}
就像显式用法一样,这个带有正则表达式的信号也会停止schema1.table1和schema2.table2。
使用 SQL 条件应用过滤器
虽然不常见,但可能会出现连接器配置错误等情况,其中需要将特定记录或记录子集重新发送到主题。不幸的是,增量快照传统上是一种全有或全无类型的过程,我们会重新发出集合或表中的所有记录作为快照的一部分。
在此版本中,可以在信号负载中指定一个新additional-condition属性,允许信号指示基于 SQL 的谓词来控制增量快照中应包含哪些记录子集,而不是所有行的默认行为。
以下示例说明了为表发送增量快照信号products,但不是将表中的所有行发送到主题,而是additional-condition指定属性以限制快照仅发送与产品 ID 相关的事件等于12:
{
"type": "execute-snapshot",
"data": {
"data-collections": ["inventory.products"],
"type": "INCREMENTAL",
"additional-condition": "product_id=12"
}
}
我们相信,出于各种原因,这种新的增量快照功能将非常有用,而无需在只需要数据子集时总是重新拍摄所有行的快照。
信号数据库集合自动添加到包含过滤器
在之前的 Debezium 版本中,用于增量快照的信号集合/表必须手动添加到您的table.include.list连接器属性中。此版本的一大主题是对增量快照的改进,因此我们也借此机会对其进行了简化。从此版本开始,Debezium 将自动将信号集合/表格添加到表格包含过滤器中,无需用户手动添加。
此更改不会造成任何兼容性问题。已在属性中包含信号集合/表的连接器配置table.include.list将继续工作,无需任何更改。但是,如果您希望使您的配置与当前行为保持一致,您也可以安全地从中删除信号集合/表table.include.list,Debezium 将开始自动为您处理。
事务元数据事件描述数据库事务的开始和结束(提交)。这些事件有多种用途,包括审计。默认情况下,事务元数据事件不是由连接器生成的,要启用此功能,provide.transaction.metadata必须启用该选项。
在 Debezium 2.0 中,BEGIN和END事件都包含一个新字段,ts_ms它是事务开始或提交的数据库时间戳,具体取决于事件类型。此类事件的示例现在如下所示:
{
"status": "END",
"id": "12345",
"event_count": 2,
"ts_ms": "1657033173441",
"data_collections": [
{
"data_collection": "s1.a",
"event_count": 1
},
{
"data_collection": "s2.a",
"event_count": 1
}
]
}
如果您已经在使用交易元数据功能,升级后新事件将包含此字段。
如果您没有使用事务元数据功能但发现这很有用,只需将provide.transaction.metadata选项设置为true添加到您的连接器配置。默认情况下,元数据事件会发送到以您的topic.prefix选项命名的主题。这可以通过指定transaction.topic选项来覆盖,如下所示:
topic.prefix=server1
provide.transaction.metadata=true
transaction.topic=my-transaction-events
在此示例中,所有事务元数据事件都将发送到my-transaction-events. 有关更多详细信息,请参阅您的连接器特定配
许多数据库平台开箱即用地支持多租户,这意味着您可以安装一次数据库引擎并拥有许多独特的数据库。在像 SQL Server 这样的情况下,传统上这需要为每个唯一的数据库部署单独的连接器。在过去的一年里,人们付出了巨大的努力来打破这个障碍,并引入一种通用的方式,任何单一的连接器部署都可以连接并流式传输来自多个数据库的更改。
第一个值得注意的变化是 SQL Server 连接器的配置选项,database.dbname. 此选项已替换为名为 的新选项database.names。由于多分区模式现在是默认模式,因此database.names可以使用以逗号分隔的数据库名称列表来指定此新选项,如下所示:
database.names=TEST1,TEST2
在此示例中,连接器被配置为捕获来自同一主机安装上的两个唯一数据库的更改。连接器将在 Kafka Connect 中启动两个独特的任务,每个任务将负责同时从其各自的数据库流式传输更改。
第二个显着变化是连接器指标命名。连接器通过使用唯一名称标识的 bean 公开 JMX 指标。多分区模式默认有多个任务,每个任务都需要自己的度量 bean,因此有必要更改命名策略。
在旧版本的 Debezium 中,以 SQL Server 为例,指标可以使用以下命名策略:
debezium.sql_server:type=connector-metrics,server=<sqlserver.server.name>,context=<context>
在此版本中,命名策略现在task在 JMX MBean 名称中包含一个新组件:
debezium.sql_server:type=connector-metrics,server=<sqlserver.server.name>,task=<task.id>,context=<context>
请检查您的指标配置,因为命名更改可能会影响收集 Debezium 指标。
在此版本中,我们debezium-storage为基于文件和基于 kafka 的数据库历史记录和偏移量存储引入了一组新的工件。此更改是为支持 Amazon S3、Redis 和可能的 JDBC 等平台而设置的多个未来实现中的第一个。
对于通过插件工件安装连接器的用户,这应该是一个无缝的更改,因为所有依赖项都捆绑在这些插件可下载档案中。对于可能将 Debezium 嵌入到他们的应用程序中或可能正在构建自己的连接器的用户,请注意您可能需要添加新的存储依赖项,具体取决于使用的存储实现。
Debezium 的默认主题命名策略向名为 的主题发出更改事件database.schema.table。如果您需要以不同方式命名主题,通常会将 SMT 添加到连接器配置中以调整此行为。但是,如果此主题名称的组成部分之一(可能是数据库或表名称)包含点 ( .) 并且 SMT 可能没有足够的上下文,这会带来挑战。
在此版本中,TopicNamingStrategy引入了一个新功能以允许直接在 Debezium 中完全自定义此行为。在大多数情况下,默认命名策略实现应该足够了,但如果您发现它不够用,您可以提供TopicNamingStrategy合同的自定义实现以完全控制连接器使用的各种命名。要提供您自己的自定义策略,您可以使用策略topic.naming.strategy的完全限定类名称指定连接器选项,如下所示:
topic.naming.strategy=org.myorganization.MyCustomTopicNamingStrategy
这种自定义策略不仅限于控制表映射的主题名称,还可以控制模式更改、事务元数据和心跳。
Debezium 连接器不必为表提供主键。在未定义主键的情况下,Debezium 将检查表的唯一索引以查看是否可以进行合理的键替换。在某些情况下,索引可能引用CTIDPostgreSQL 或ROWIDOracle 中的列。这些列不可见,也不是用户定义的,而是数据库自动生成的隐藏合成列。此外,索引还可以使用数据库函数来转换存储的列值,例如UPPER或LOWER例如。
在此版本中,依赖于隐藏的、自动生成的列或包含在数据库函数中的列的索引不再有资格作为主键替代项。这保证了当依靠索引作为主键而不是定义的主键本身时,生成的消息的主键值元组直接映射到数据库使用的相同值来表示唯一性。
Debezium 2.0 最大的改革之一是引入了新的连接器属性命名空间。从 Debezium 2.0 Beta2 开始,许多连接器属性已使用新名称重新定位。这是一项重大更改,在升级过程中会影响大多数(如果不是全部的话)连接器部署。
Debezium 以前使用前缀“数据库”。具有多种多样的连接器特性。其中一些属性旨在直接传递给 JDBC 驱动程序,在其他情况下传递给数据库历史记录实现,等等。不幸的是,我们发现了一些情况,其中一些属性被传递给了非预期的底层实现。虽然这不会造成任何类型的回归或问题,但如果存在属性名称冲突(例如,与“数据库”匹配的 JDBC 驱动程序属性),它可能会在未来引入问题。带前缀的 Debezium 连接器属性。
下面介绍连接器属性的变化:
同样,请在部署之前检查您的连接器配置并进行相应调整。
Debezium 更改事件随模式定义一起发出,其中包含有关字段的元数据,例如类型、是否需要等等。在之前的 Debezium 迭代中,一些模式定义没有明确的名称,也没有明确的版本控制。在此版本中,我们已着手确保所有架构定义都具有明确的名称和与之关联的版本。此更改的目标是帮助实现未来的事件结构兼容性,特别是对于那些使用模式注册表的人。但是,如果您当前正在使用架构注册表,请注意此更改可能会导致升级过程中出现架构兼容性问题。
默认情况下会跳过截断事件
skipped.operationsDebezium 通过在连接器的配置中包含连接器属性来支持跳过特定的事件类型。如果您只对操作的子集感兴趣,例如仅插入和更新而不是删除,则此功能可能很有用。
一种特定的事件类型,截断 ( t),仅受关系连接器子集的支持,并且是否要跳过这些事件并不一致。在此版本中,我们调整了skipped.operations行为,以便如果连接器支持截断事件,则默认情况下会跳过这些事件。
请查看以下规则集:
如果以上所有情况都成立,则连接器的行为将在升级后发生变化。如果您希望继续发出截断事件,则skipped.operations=none需要进行配置。
schema.name.adjustment行为改变
配置属性控制应如何调整模式名称以schema.name.adjustment.mode与连接器使用的消息转换器兼容。此配置选项可以是以下两个值之一:
在以前的版本中,Debezium 始终默认为安全值avro;但是,从 Debezium 2.0.0.CR1 开始,默认值现在是none. 我们认为,鉴于 Avro 序列化的使用是用户根据他们的需要选择加入的,这个选项应该与相同的选择加入行为保持一致。
安全的升级路径是调整您的配置并明确使schema.name.adjustment.modeasavro并使用新连接器部署的默认值。但是您也可以检查您的主题名称和配置,检查没有发生下划线替换,因此此更改不会产生任何影响。
删除了旧版 MySQL 实现
正如你们中的某些人可能知道或可能不知道的那样,我们在 Debezium 1.5(2021 年 2 月)中基于通用连接器框架实现了 MySQL 连接器。作为重写的一部分,我们为 MySQL 用户引入了使用配置选项internal.implementation设置为legacy. 为了支持新的公共连接器框架行为,这个遗留的实现被弃用了。在 Debezium 2.0 中,此internal.implementation配置选项和遗留连接器实现已被删除。
如果您当前的连接器部署依赖于此遗留实现,您应该知道,通过升级到 Debezium 2.0,连接器将不再使用旧的实现,而将仅使用通用连接器实现。就功能而言,这两种实现都彼此相同,但有一个例外:遗留实现具有对更改过滤器配置的实验性支持。如果您依赖于此遗留行为,请注意该功能不再可用。
Cassandra 4 增量提交日志支持
Cassandra 4通过添加一项功能改进了与 CDC 的集成,即当发生 fsync 操作时,Cassandra 将更新基于 CDC 的索引文件以包含最新的偏移值。此索引文件允许 CDC 实现读取 Cassandra 中认为持久的偏移量。
在此版本中,Debezium 现在使用这个基于 CDC 的索引文件来消除以前存在的处理来自 Cassandra 的 CDC 事件的固有延迟。这应该为 Cassandra 用户提供 Debezium 的 CDC 的实质性改进,并激励他们考虑 Cassandra 4 而不是 Cassandra 3。
Binlog 压缩支持
在此版本中,Debezium 现在支持读取已启用压缩的二进制日志条目。在 8.0.20 版本中,MySQL 增加了使用 ZSTD 算法压缩 binlog events 的能力。要启用压缩,您必须binlog.transaction_compression将 MySQL 服务器上的变量切换为ON. 启用压缩后,binlog 的行为与往常一样,除了 binlog 条目的内容被压缩以节省空间,并以压缩格式复制到副本,显着减少了较大事务的网络开销。
如果您有兴趣阅读有关 MySQL binlog 压缩的更多信息,可以参考 MySQL 文档的二进制日志事务压缩部分以了解更多详细信息。
删除 oplog 实现
在 Debezium 1.8 中,我们引入了新的 MongoDB 更改流功能,同时也弃用了 oplog 实现。向变更流的过渡提供了多种好处,例如能够从非主节点流式传输变更,能够为下游消费者发出具有完整文档表示的更新事件,等等。简而言之,变更流只是使用 MongoDB 执行变更数据捕获的一种更优越的方式。
删除 oplog 实现也意味着不再支持 MongoDB 3.x。如果您使用的是 MongoDB 3.x,则需要使用 Debezium 2.0 至少升级到 MongoDB 4.0 或更高版本。
前状态支持(MongoDB 6.0)
MongoDB 6 支持在应用更改之前捕获文档的状态。长期以来,这一直是一项仅适用于基于关系的连接器的功能,但现在这使 Debezium 也可以将该before字段作为 MongoDB 事件负载的一部分。
为了启用这个新的 MongoDB 6+ 行为,capture.mode设置已被调整为包括两个新值:
change_streams_with_pre_image
更改事件还将包含更改之前的完整文档以及作为更改事件的一部分更改的文档字段的最终状态。
change_streams_update_full_with_pre_image
发生更新时,不仅会出现完整文档以表示更新后的当前状态,而且事件还将包含更改前的完整文档。
MongoDBbefore字段行为仅适用于 MongoDB 6 或更高版本。如果您使用的是 6.0 之前的 MongoDB 版本before,即使已配置,该字段也会从事件输出中省略。
Oracle 源信息更改
信息块是更改事件有效负载中的source一个部分,它描述了生成更改事件的数据库属性。例如,此部分包括系统更改编号、更改的数据库时间戳以及更改所属的事务。
在此版本中,我们发现了一个回归,其中scn字段未正确反映source更改事件发生位置的正确性。虽然 Oracle 使用相同的系统更改编号生成多个更改并不异常,但我们确实发现了一个回归,导致错误的系统更改编号被分配给范围事务中的每个单独的事件,这使得一些人很难将此信息用于审计目的。该source.scn字段现在应该正确反映来自 Oracle LogMiner 或 Oracle Xstream 的系统更改编号。
此外,信息块中添加了几个新字段,source以改进与 LogMiner 实施和 Oracle RAC 的集成。新源信息块示例:
{
"source": {
"version": "2.0.0.Alpha3",
"name": "server1",
"ts_ms": 1520085154000,
"txId": "6.28.807",
"scn": "2122184",
"commit_scn": "2122185",
"rs_id": "001234.00012345.0124",
"ssn": 0,
"redo_thread": 1
}
}
新增的字段有:
无论是使用 Oracle Standalone 还是 RAC,在使用 Oracle LogMiner 时都将始终提供这些值。这些值对 Oracle RAC 安装更为重要,因为您有多个数据库服务器同时操作共享数据库。这些字段专门注释更改源自哪个节点以及该节点上的哪个位置。
Oracle 连接器偏移量更改
在 Oracle Real Application Clusters (RAC) 环境中,多个节点同时访问和操作 Oracle 数据库。每个节点维护自己的重做日志缓冲区并执行自己的重做写入器线程。这意味着在任何给定时刻,每个节点都有自己独特的“位置”,并且这些位置在每个节点上发生的活动上完全不同。
在此版本中,需要对DBZ-5245进行小改动以支持 Oracle RAC。以前,连接器偏移量维护一个名为的字段,该字段scn表示连接器应从中流式传输更改的“位置”。但是由于每个节点可能位于重做中的不同位置,因此单个scn值对于 Oracle RAC 是不够的。
旧的 Oracle 连接器偏移量如下所示:
{
"scn": "1234567890",
"commit_scn": "2345678901",
"lcr_position": null,
"txId": null
}
从 Debezium 2.0 开始,新的偏移量结构现在具有以下形式:
{
"scn": "1234567890:00124.234567890.1234:0:1,1234567891:42100.0987656432.4321:0:2",
"commit_scn": "2345678901",
"lcr_position": null,
"txId": null
}
您会注意到该scn字段现在由逗号分隔的值列表组成,其中每个条目代表一个值元组。这个新元组的格式为scn:rollback-segment-id:ssn:redo-thread.
此更改是向前兼容的,这意味着一旦您升级到 Debezium 2.0,旧版本的连接器将无法读取偏移量。如果您确实升级并决定回滚,请注意偏移量将需要手动调整偏移量的字段以仅包含所有重做线程scn中的最新值的字符串。scn
Oracle 在更改事件中提交用户
更改事件的源信息块包含有关更改事件起源位置的各种上下文。在此版本中,Oracle 连接器现在包括在捕获的更改事件中进行数据库更改的用户。user_name现在可以在包含此新信息的源信息块中找到一个新字段。此字段是可选的,并且仅在使用基于 LogMiner 的实现发出更改时可用。UNKNOWN如果在连接器捕获更改之前删除与更改关联的用户,则此字段还可能包含值。
删除了对 wal2json 的支持
在 Debezium 的整个生命周期中,PostgreSQL 连接器支持多种解码器实现,包括decoderbufs、wal2json和pgoutput。decoderbufs和插件都wal2json需要在数据库服务器上安装特殊的库来捕获来自 PostgreSQL 的更改。
随着 PostgreSQL 9.6 于 2021 年 11 月被标记为生命周期结束,我们认为现在是精简支持的解码器数量的绝佳机会。随着 PostgreSQL 10 及更高版本原生支持pgoutput解码器,我们得出结论,在 Debezium 2.0 中删除对wal2json插件的支持是有意义的。
如果您仍在使用 PostgreSQL 9.6 或wal2json解码器,则需要升级到 PostgreSQL 10+ 或升级到decoderbufs本机pgoutput插件才能继续使用 Debezium。
对 Vitess 的多任务支持
Vitess 连接器以前允许在两种不同的模式下运行,这完全取决于连接器配置是否指定了任何分片细节。不幸的是,在这两种情况下,每种情况都会产生一个负责执行 VStream 处理的任务。对于具有许多分片的大型 Vitess 安装,这种架构可能会开始出现延迟问题,因为它可能无法跟上所有分片的所有变化。更复杂的是,在指定分片详细信息时,这需要手动解析整个集群的分片并为每个分片启动一个 Debezium 连接器,这既容易出错,更重要的是可能导致部署许多 Debezium 连接器。
Vitess 社区认识到了这一点,并试图从维护和错误的角度找到解决所有这些问题的解决方案。在 Debezium 2.0 Beta2 中,Vitess 连接器现在通过发现机制自动解析分片,这与 MongoDB 非常相似。然后,此发现机制会将负载拆分到多个任务中,允许 Debezium 的单个部署在每个分片或分片列表中运行一个任务,具体取决于连接器允许的最大任务数。
在升级期间,Vitess 连接器会自动将偏移量存储迁移到与多任务处理行为一起使用的新格式。但请注意,一旦升级,您将无法降级到较早的版本,因为偏移量存储格式会发生变化。
支持 ARM64
近年来,ARM64 的性能发生了变化,即使在 AWS,其 64 位 ARM 处理器的性能也超过了最新的 x86-64 处理器。这有助于在整个行业中强调使用容器支持这两种架构的成本效益。
由于 Debezium 传统上发布了linux/amd64基于 的容器镜像,这要求您使用虚拟机内部的模拟运行镜像。这会导致不必要的开销和潜在的性能问题,Debezium 的目标是低延迟和超高速!从 Debezium 2.0 开始,Debezium 现在也使用ARM64基于 的容器镜像发布,减少了所需的开销。
我们希望新的 ARM64 容器镜像能够提高 Debezium 的采用率,并表明我们致力于在整个行业范围内提供最佳的变更数据捕获体验。