先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
正文
四、MongoDB 连接器的工作原理
连接器支持的 MongoDB 拓扑概述对于规划您的应用程序非常有用。
配置和部署 MongoDB 连接器时,它首先连接到种子地址处的 MongoDB 服务器,并确定有关每个可用副本集的详细信息。由于每个副本集都有自己独立的oplog,因此连接器将尝试为每个副本集使用单独的任务。连接器可以限制它将使用的最大任务数,如果没有足够的任务可用,连接器将为每个任务分配多个副本集,尽管该任务仍将为每个副本集使用单独的线程。
针对分片集群运行连接器时,请使用大于副本集数量的tasks.max 值。这将允许连接器为每个副本集创建一个任务,并让 Kafka Connect 协调、分配和管理所有可用工作进程中的任务。
五、支持的 MongoDB 拓扑
MongoDB 连接器支持以下 MongoDB 拓扑:
- MongoDB 副本集
- Debezium MongoDB 连接器可以捕获单个 MongoDB 副本集的更改。生产副本集至少需要三个成员。
- 要将 MongoDB 连接器与副本集结合使用,必须将连接器配置中的mongodb.connection.string 属性的值设置为副本集连接字符串。当连接器准备好开始从 MongoDB 更改流捕获更改时,它会启动连接任务。然后,连接任务使用指定的连接字符串建立与可用副本集成员的连接。
MongoDB 分片集群
- MongoDB 分片集群包括:
- 一个或多个分片,每个分片部署为一个副本集;
- 充当集群配置服务器的单独副本集
- 客户端连接的一个或多个路由器(也称为 mongos),并将请求路由到适当的分片
- 要将 MongoDB 连接器与分片集群结合使用,请在连接器配置中,将 mongodb.connection.string 属性的值设置为分片集群连接字符串。
mongodb.connection.string 属性替换了已删除的 mongodb.hosts 属性,该属性用于为早期版本的连接器提供配置服务器副本的主机地址。在当前版本中,使用 mongodb.connection.string 为连接器提供 MongoDB 路由器(也称为 mongos)的地址。
当连接器连接到分片集群时,它会发现有关代表集群中分片的每个副本集的信息。连接器使用单独的任务来捕获每个分片的更改。当在集群中添加或删除分片时,连接器会动态调整任务数量以补偿变化。
MongoDB 独立服务器:
- MongoDB 连接器无法监视独立 MongoDB 服务器的更改,因为独立服务器没有 oplog。如果独立服务器转换为具有一名成员的副本集,则连接器将起作用。
MongoDB 不建议在生产中运行独立服务器。
六、所需的用户权限
为了从 MongoDB 捕获数据,Debezium 以 MongoDB 用户身份连接到数据库。您为 Debezium 创建的 MongoDB 用户帐户需要特定的数据库权限才能从数据库中读取数据。连接器用户需要以下权限:
- 从数据库中读取。
- 运行 ping 命令。
连接器用户可能还需要以下权限:
- 从 config.shards 系统集合中读取。
数据库读取权限
连接器用户必须能够从所有数据库读取,或从特定数据库读取,具体取决于连接器的 capture.scope 属性的值。根据 capture.scope 设置,向用户分配以下权限之一:
- capture.scope 设置为部署:授予用户读取任何数据库的权限。
- capture.scope 设置为数据库:授予用户读取连接器的 capture.target 属性指定的数据库的权限。
使用 MongoDB ping 命令的权限
- 无论 capture.scope 设置如何,用户都需要权限才能运行 MongoDB ping 命令。
读取 config.shards 集合的权限
- 对于从分片 MongoDB 集群集群更改且 mongodb.connection.mode 属性设置为replica_set 的连接器,必须配置用户读取 config.shards 系统集合的权限。
七、逻辑连接器名称
连接器配置属性 topic.prefix 用作 MongoDB 副本集或分片集群的逻辑名称。连接器以多种方式使用逻辑名称:作为所有主题名称的前缀,以及在记录每个副本集的更改流位置时作为唯一标识符。
应该为每个 MongoDB 连接器指定一个唯一的逻辑名称,以有意义地描述源 MongoDB 系统。我们建议逻辑名称以字母或下划线字符开头,其余字符为字母数字或下划线。
八、执行快照
当 Debezium 任务开始使用副本集时,它使用连接器的逻辑名称和副本集名称来查找描述连接器先前停止读取更改的位置的偏移量。如果可以找到偏移量并且它仍然存在于 oplog 中,则任务立即从记录的偏移位置开始继续进行流式更改。
但是,如果未找到偏移量,或者 oplog 不再包含该位置,则任务必须首先通过执行快照来获取副本集内容的当前状态。该过程首先记录 oplog 的当前位置并将其记录为偏移量(以及表示快照已启动的标志)。然后,该任务继续复制每个集合,生成尽可能多的线程(最多为 snapshot.max.threads 配置属性的值)以并行执行此工作。连接器为其看到的每个文档记录一个单独的读取事件。每个读取事件都包含对象的标识符、对象的完整状态以及有关找到该对象的 MongoDB 副本集的源信息。源信息还包括一个标志,表示该事件是在快照期间生成的。
此快照将继续,直到复制了与连接器的过滤器匹配的所有集合。如果连接器在任务快照完成之前停止,则连接器重新启动后将再次开始快照。
当连接器执行任何副本集的快照时,尽量避免任务重新分配和重新配置。连接器生成日志消息来报告快照的进度。为了提供最大程度的控制,请为每个连接器运行单独的 Kafka Connect 集群。
九、临时快照
默认情况下,连接器仅在首次启动后运行初始快照操作。在此初始快照之后,在正常情况下,连接器不会重复快照过程。连接器捕获的任何未来更改事件数据仅通过流处理传入。
但是,在某些情况下,连接器在初始快照期间获取的数据可能会过时、丢失或不完整。为了提供重新捕获收集数据的机制,Debezium 包含一个执行临时快照的选项。在 Debezium 环境中发生以下任何更改后,可能需要执行临时快照:
- 修改连接器配置以捕获一组不同的集合。
- Kafka 主题已删除,必须重建。
- 由于配置错误或其他一些问题,会发生数据损坏。
可以通过启动所谓的临时快照为之前捕获快照的集合重新运行快照。特别快照需要使用信令集合。可以通过向 Debezium 信令集合发送信号请求来启动临时快照。
当启动现有集合的临时快照时,连接器会将内容附加到该集合已存在的主题中。如果删除了先前存在的主题,并且启用了自动主题创建,Debezium 可以自动创建主题。
即席快照信号指定要包含在快照中的集合。快照可以捕获数据库的全部内容,也可以仅捕获数据库中集合的子集。
可以通过向信令集合发送执行快照消息来指定要捕获的集合。将执行快照信号的类型设置为增量或阻塞,并提供要包含在快照中的集合的名称,如下表所述:
表 2. 即席执行快照信号记录示例
字段 | 默认值 | 值 |
---|---|---|
type | incremental | 指定要运行的快照的类型。目前,您可以请求增量快照或阻塞快照。 |
data-collections | N/A | 包含与要快照的集合的完全限定名称匹配的正则表达式的数组。名称的格式与 signal.data.collection 配置选项相同。 |
触发临时增量快照
您可以通过将具有执行快照信号类型的条目添加到信令集合来启动临时增量快照。连接器处理消息后,开始快照操作。快照进程读取第一个和最后一个主键值,并将这些值用作每个集合的起点和终点。根据集合中的条目数和配置的块大小,Debezium 将集合划分为块,并继续对每个块进行快照,一次一个。
触发临时阻塞快照
您可以通过将具有执行快照信号类型的条目添加到信令集合来启动临时阻塞快照。连接器处理消息后,开始快照操作。连接器暂时停止流式传输,然后启动指定集合的快照,遵循初始快照期间使用的相同过程。快照完成后,连接器将恢复流式传输。
十、增量快照
为了提供管理快照的灵活性,Debezium 包含一个补充快照机制,称为增量快照。增量快照依赖 Debezium 机制向 Debezium 连接器发送信号。增量快照基于DDD-3设计文档。
在增量快照中,Debezium 不像初始快照那样一次性捕获数据库的完整状态,而是以一系列可配置块的形式分阶段捕获每个集合。您可以指定希望快照捕获的集合以及每个块的大小。块大小确定快照在数据库上的每个提取操作期间收集的行数。增量快照的默认块大小为 1024 行。
随着增量快照的进行,Debezium 使用水印来跟踪其进度,维护其捕获的每个集合行的记录。与标准初始快照过程相比,这种分阶段捕获数据的方法具有以下优点:
- 您可以与流数据捕获并行运行增量快照,而不是推迟流数据直到快照完成。连接器在整个快照过程中持续从更改日志中捕获近乎实时的事件,并且两个操作都不会阻塞另一个操作。
- 如果增量快照的进度中断,您可以恢复增量快照而不会丢失任何数据。进程恢复后,快照会从停止点开始,而不是从头开始重新捕获集合。
- 您可以随时按需运行增量快照,并根据需要重复该过程以适应数据库更新。例如,您可以在修改连接器配置以将集合添加到其 collection.include.list 属性后重新运行快照。
1.增量快照流程
当您运行增量快照时,Debezium 按主键对每个集合进行排序,然后根据配置的块大小将集合拆分为块。逐块工作,然后捕获块中的每个集合行。对于它捕获的每一行,快照都会发出一个 READ 事件。该事件表示块快照开始时行的值。
随着快照的进行,其他进程可能会继续访问数据库,从而可能修改集合记录。为了反映此类更改,INSERT、UPDATE 或 DELETE 操作将照常提交到事务日志。同样,正在进行的 Debezium 流处理继续检测这些更改事件并将相应的更改事件记录发送到 Kafka。
2.Debezium 如何解决具有相同主键的记录之间的冲突
在某些情况下,流处理发出的 UPDATE 或 DELETE 事件的接收顺序不正确。也就是说,在快照捕获包含该行的 READ 事件的块之前,流处理可能会发出一个修改集合行的事件。当快照最终发出该行相应的 READ 事件时,其值已被取代。为了确保按正确的逻辑顺序处理不按顺序到达的增量快照事件,Debezium 采用缓冲方案来解决冲突。仅当快照事件和流式事件之间的冲突得到解决后,Debezium 才会向 Kafka 发送事件记录。
3.快照窗口
为了帮助解决迟到的 READ 事件和修改同一集合行的流式事件之间的冲突,Debezium 采用了所谓的快照窗口。快照窗口划定了增量快照捕获指定收集块的数据的时间间隔。在块的快照窗口打开之前,Debezium 会遵循其通常的行为,并将事件从事务日志直接向下游发送到目标 Kafka 主题。但从特定块的快照打开的那一刻起,直到其关闭,Debezium 都会执行重复数据删除步骤来解决具有相同主键的事件之间的冲突。
对于每个数据收集,Debezium 会发出两种类型的事件,并将它们的记录存储在单个目标 Kafka 主题中。它直接从表中捕获的快照记录作为 READ 操作发出。同时,随着用户继续更新数据集合中的记录,并且更新事务日志以反映每次提交,Debezium 会针对每次更改发出 UPDATE 或 DELETE 操作。
当快照窗口打开时,Debezium 开始处理快照块,它将快照记录传送到内存缓冲区。在快照窗口期间,缓冲区中 READ 事件的主键与传入流事件的主键进行比较。如果未找到匹配项,则流式事件记录将直接发送到 Kafka。如果 Debezium 检测到匹配,它会丢弃缓冲的 READ 事件,并将流式记录写入目标主题,因为流式事件在逻辑上取代静态快照事件。块的快照窗口关闭后,缓冲区仅包含不存在相关事务日志事件的 READ 事件。 Debezium 将这些剩余的 READ 事件发送到集合的 Kafka 主题。
连接器对每个快照块重复该过程。
增量快照需要主键稳定有序。但是,字符串可能无法保证稳定的排序,因为编码和特殊字符可能会导致意外行为(Mongo 排序字符串)。执行增量快照时请考虑使用其他类型的主键。
4.分片集群的增量快照
要将增量快照与分片 MongoDB 集群一起使用,您必须为以下属性设置特定值:
- 将 mongodb.connection.mode 设置为分片。
- 将incremental.snapshot.chunk.size设置为足够高的值,以补偿变更流管道增加的复杂性。
5.触发增量快照
目前,启动增量快照的唯一方法是将临时快照信号发送到源数据库上的信令集合。
您可以使用 MongoDB insert() 方法向信令集合提交信号。
Debezium 检测到信号集合中的变化后,它会读取信号,并运行请求的快照操作。
您提交的查询指定要包含在快照中的集合,并且可以选择指定快照操作的类型。目前,快照操作的唯一有效选项是默认值增量。
要指定要包含在快照中的集合,请提供一个列出集合的数据集合数组或用于匹配集合的正则表达式数组,例如,{“data-collections”: [“public.Collection1”, “public.Collection2”]}
增量快照信号的数据收集数组没有默认值。如果数据收集数组为空,Debezium 会检测到不需要执行任何操作,并且不会执行快照。
如果要包含在快照中的集合的名称在数据库、架构或表的名称中包含点 (.),则要将该集合添加到数据集合数组中,必须转义该集合的每个部分名称用双引号引起来。
例如,要包含公共数据库中存在且名称为 My.Collection 的数据集合,请使用以下格式:“public”.“My.Collection”。
先决条件
- 信令已启用。
- 源数据库中存在信令数据集合。
- 信令数据收集在 signal.data.collection 属性中指定。
使用源信令通道触发增量快照
- 将快照信号文档插入到信令集合中:
.insert({“id” : _,“type” : , “data” : {“data-collections” [“”, “”],“type”: }});
例如,
db.debeziumSignal.insert({
“type” : “execute-snapshot”,
“data” : {
“data-collections” ["“public”.“Collection1"”, "“public”.“Collection2"”],
“type”: “incremental”}
});
命令中的id、type、data参数的取值与信令集合的字段相对应。
示例中的参数说明如下表:
表 3. 用于将增量快照信号发送到信令集合的 MongoDB insert() 命令中的字段描述
1 | db.debeziumSignal | 指定源数据库上信令集合的完全限定名称。 |
2 | null | _id 参数指定指定为信号请求的 id 标识符的任意字符串。前面示例中的 insert 方法省略了可选 _id 参数的使用。由于文档没有显式地为参数分配值,因此 MongoDB 自动分配给文档的任意 id 就成为信号请求的 id 标识符。使用此字符串来标识信令集合中条目的日志消息。 Debezium 不使用此标识符字符串。相反,在快照期间,Debezium 会生成自己的 id 字符串作为水印信号。 |
3 | execute-snapshot | 指定类型参数指定信号要触发的操作。 |
4 | data-collections | 信号数据字段的必需组件,指定集合名称或正则表达式的数组,以匹配要包含在快照中的集合名称。该数组列出了通过完全限定名称匹配集合的正则表达式,使用与在 signal.data.collection 配置属性中指定连接器信令集合名称相同的格式。 |
5 | incremental | 信号数据字段的可选类型组件,指定要运行的快照操作的类型。目前,唯一有效的选项是默认值增量。如果不指定值,连接器将运行增量快照。 |
以下示例显示了连接器捕获的增量快照事件的 JSON。
示例:增量快照事件消息
{
“before”:null,
“after”: {
“pk”:“1”,
“value”:“New data”
},
“source”: {
…
“snapshot”:“incremental” 1
},
“op”:“r”, 2
“ts_ms”:“1620393591654”,
“transaction”:null
}
选项 | 字段名称 | 描述 |
---|---|---|
1 | snapshot | 指定要运行的快照操作的类型。目前,唯一有效的选项是默认值增量。在提交到信令集合的 SQL 查询中指定类型值是可选的。如果不指定值,连接器将运行增量快照。 |
2 | op | 指定事件类型。快照事件的值为r,表示READ操作。 |
6.使用Kafka信令通道触发增量快照
您可以向配置的 Kafka 主题发送消息,请求连接器运行临时增量快照。
Kafka 消息的键必须与 topic.prefix 连接器配置选项的值匹配。
消息的值是一个带有类型和数据字段的 JSON 对象。
信号类型为execute-snapshot,数据字段必须有以下字段:
表 4. 执行快照数据字段
字段 | 默认值 | 值 |
---|---|---|
type | incremental | 要执行的快照的类型。目前 Debezium 仅支持增量类型。 |
data-collections | N/A | 一组以逗号分隔的正则表达式,与要包含在快照中的表的完全限定名称相匹配。使用与 signal.data.collection 配置选项所需的格式相同的格式指定名称。 |
additional-condition | N/A | 一个可选字符串,指定连接器评估的条件,以指定要包含在快照中的记录子集。此属性已弃用,应由附加条件属性替换。 |
additional-conditions | N/A | 附加条件的可选数组,指定连接器评估的条件以指定要包含在快照中的记录子集。每个附加条件都是一个对象,指定过滤临时快照捕获的数据的条件。您可以为每个附加条件设置以下参数: data-collection:: 过滤器应用到的集合的完全限定名称。您可以对每个集合应用不同的过滤器。 filter:: 指定数据库记录中必须存在的列值,快照才能包含该列值,例如“color=‘blue’”。您分配给过滤器参数的值与您在为阻塞快照设置 snapshot.select.statement.overrides 属性时可能在 SELECT 语句的 WHERE 子句中指定的值类型相同。在早期 Debezium 版本中,没有为快照信号定义显式过滤器参数;相反,过滤条件是由为现已弃用的附加条件参数指定的值隐含的。 |
执行快照 Kafka 消息的示例:
Key = test\_connector
Value = {"type":"execute-snapshot","data": {"data-collections": ["schema1.table1", "schema1.table2"], "type": "INCREMENTAL"}}
7.具有附加条件的临时增量快照
Debezium 使用附加条件字段来选择集合内容的子集。
通常,当 Debezium 运行快照时,它会运行 SQL 查询,例如:
SELECT * FROM ….
当快照请求包含附加条件属性时,该属性的数据收集和过滤参数将附加到 SQL 查询中,例如:
SELECT * FROM WHERE ….
例如,给定一个包含 id(主键)、颜色和品牌列的产品集合,如果您希望快照仅包含 color=‘blue’ 的内容,则当您请求快照时,您可以添加附加 -用于过滤内容的条件属性:
Key = test\_connector
Value = {"type":"execute-snapshot","data": {"data-collections": ["schema1.products"], "type": "INCREMENTAL", "additional-conditions": [{"data-collection": "schema1.products" ,"filter":"color='blue'"}]}}
您可以使用additional-conditions 属性来传递基于多列的条件。例如,使用与上一示例中相同的产品集合,如果您希望快照仅包含产品集合中 color=‘blue’、brand=‘MyBrand’ 的内容,则可以发送以下请求:
Key = test\_connector
Value = {"type":"execute-snapshot","data": {"data-collections": ["schema1.products"], "type": "INCREMENTAL", "additional-conditions": [{"data-collection": "schema1.products" ,"filter":"color='blue' AND brand='MyBrand'"}]}}
8.停止增量快照
您还可以通过向源数据库上的集合发送信号来停止增量快照。您可以通过将文档插入信号集合来提交停止快照信号。 Debezium 检测到信号集合中的变化后,会读取信号,并停止正在进行的增量快照操作。
您提交的查询指定增量快照操作,以及(可选)要删除的当前运行快照的集合。
先决条件
- 信令已启用。
- 源数据库中存在信令数据集合。
- 信令数据收集在 signal.data.collection 属性中指定。
使用源信令通道停止增量快照
- 将停止快照信号文档插入到信号集合中:
.insert({“id” : _,“type” : “stop-snapshot”, “data” : {“data-collections” [“”, “”],“type”: “incremental”}});
例如,
db.debeziumSignal.insert({
“type” : “stop-snapshot”,
“data” : {
“data-collections” ["“public”.“Collection1"”, "“public”.“Collection2"”],
“type”: “incremental”}
});
signal命令中的id、type、data参数的取值对应于信令集合的字段。
示例中的参数说明如下表:
表5 向信令集合发送停止增量快照文档的插入命令字段说明
选项 | 值 | 描述 |
---|---|---|
1 | db.debeziumSignal | 指定源数据库上信令集合的完全限定名称。 |
2 | null | 前面示例中的 insert 方法省略了可选 _id 参数的使用。由于文档没有显式地为参数分配值,因此 MongoDB 自动分配给文档的任意 id 就成为信号请求的 id 标识符。使用此字符串来标识信令集合中条目的日志消息。 Debezium 不使用此标识符字符串。 |
3 | stop-snapshot | 类型参数指定信号要触发的操作。 |
4 | data-collections | 信号数据字段的可选组件,指定集合名称或正则表达式的数组,以匹配要从快照中删除的集合名称。该数组列出了通过完全限定名称匹配集合的正则表达式,使用与在 signal.data.collection 配置属性中指定连接器信令集合名称相同的格式。如果省略数据字段的该组成部分,则该信号将停止正在进行的整个增量快照。 |
5 | incremental | 信号数据字段的必需组成部分,指定要停止的快照操作类型。目前,唯一有效的选项是增量选项。如果不指定类型值,则信号无法停止增量快照。 |
9.使用Kafka信令通道停止增量快照
您可以向配置的 Kafka 信令主题发送信号消息以停止即席增量快照。
Kafka 消息的键必须与 topic.prefix 连接器配置选项的值匹配。
消息的值是一个带有类型和数据字段的 JSON 对象。
信号类型为stop-snapshot,数据字段必须有以下字段:
表 6. 执行快照数据字段
字段 | 默认值 | 值 |
---|---|---|
type | incremental | 要执行的快照的类型。目前 Debezium 仅支持增量类型。 |
data-collections | N/A | 一个可选的逗号分隔正则表达式数组,与要包含在快照中的表的完全限定名称相匹配。使用与 signal.data.collection 配置选项所需的格式相同的格式指定名称。 |
以下示例显示了典型的停止快照 Kafka 消息:
Key = test\_connector
Value = {"type":"stop-snapshot","data": {"data-collections": ["schema1.table1", "schema1.table2"], "type": "INCREMENTAL"}}
10.阻止快照
为了在管理快照方面提供更大的灵活性,Debezium 包含一个补充的临时快照机制,称为阻塞快照。阻止快照依赖 Debezium 机制向 Debezium 连接器发送信号。
阻塞快照的行为就像初始快照一样,只是您可以在运行时触发它。
在以下情况下,您可能希望运行阻塞快照而不是使用标准初始快照进程:
- 您添加了一个新集合,并且希望在连接器运行时完成快照。
- 您添加了一个大型集合,并且希望快照在比增量快照更短的时间内完成。
11.阻塞快照进程
当您运行阻塞快照时,Debezium 会停止流式传输,然后启动指定集合的快照,遵循初始快照期间使用的相同流程。快照完成后,流将恢复。
12.配置快照
您可以在信号的数据组件中设置以下属性:
- data-collections:指定哪些集合必须是快照
- 附加条件:您可以为不同的集合指定不同的过滤器。
- data-collection 属性是要应用过滤器的集合的完全限定名称。
- 过滤器属性将具有与 snapshot.select.statement.overrides 中使用的相同值
例如:
{“type”: “blocking”, “data-collections”: [“schema1.table1”, “schema1.table2”], “additional-conditions”: [{“data-collection”: “schema1.table1”, “filter”: “SELECT * FROM [schema1].[table1] WHERE column1 = 0 ORDER BY column2 DESC”}, {“data-collection”: “schema1.table2”, “filter”: “SELECT * FROM [schema1].[table2] WHERE column2 > 0”}]}
13.可能重复
发送信号以触发快照的时间与流停止和快照开始的时间之间可能存在延迟。由于此延迟,在快照完成后,连接器可能会发出一些与快照捕获的记录重复的事件记录。
十一、流变化
副本集的连接器任务记录偏移量后,它使用该偏移量来确定 oplog 中应开始流式传输更改的位置。然后,该任务(取决于配置)要么连接到副本集的主节点,要么连接到副本集范围的更改流并从该位置开始流式传输更改。它处理所有创建、插入和删除操作,并将它们转换为 Debezium 更改事件。每个更改事件都包含 oplog 中找到操作的位置,并且连接器会定期将其记录为最近的偏移量。记录偏移量的时间间隔由 offset.flush.interval.ms 控制,这是 Kafka Connect 工作线程配置属性。
当连接器正常停止时,会记录最后处理的偏移量,以便在重新启动时,连接器将准确地从其停止的位置继续。但是,如果连接器的任务意外终止,则任务可能在最后记录偏移量之后但在记录最后偏移量之前处理并生成事件;重新启动后,连接器从最后记录的偏移量开始,可能会生成一些与崩溃之前生成的事件相同的事件。
注意:当 Kafka 管道中的所有组件正常运行时,Kafka 消费者只会接收每条消息一次。然而,当出现问题时,Kafka 只能保证消费者至少收到每条消息一次。为了避免意外结果,消费者必须能够处理重复的消息。
如前所述,连接器任务始终使用副本集的主节点来传输来自 oplog 的更改,从而确保连接器尽可能看到最新的操作,并且能够以比辅助节点更低的延迟捕获更改。代替使用。当副本集选择新的主节点时,连接器立即停止流式传输更改,连接到新的主节点,并开始从新主节点的同一位置流式传输更改。同样,如果连接器在与副本集成员通信时遇到任何问题,它会尝试使用指数退避来重新连接,以免淹没副本集,并且一旦连接,它就会从上次停止的位置继续流式传输更改。通过这种方式,连接器能够动态调整以适应副本集成员资格的变化并自动处理通信故障。
总而言之,MongoDB 连接器在大多数情况下都会继续运行。通信问题可能会导致连接器等待问题解决。
十二、原像支持
在 MongoDB 6.0 及更高版本中,您可以配置更改流以发出文档的原像状态,以填充 MongoDB 更改事件的 before 字段。要在 MongoDB 中使用原像,您必须使用 db.createCollection()、create 或 collMod 为集合设置changeStreamPreAndPostImages。要使 Debezium MongoDB 能够在更改事件中包含原像,请将连接器的 capture.mode 设置为 *_with_pre_image 选项之一。
注意:MongoDB 更改流事件的大小限制
MongoDB 更改流事件的大小限制为 16 MB。因此,原像的使用增加了超过该阈值的可能性,这可能导致失败。
十三、主题名称
MongoDB 连接器将每个集合中文档的所有插入、更新和删除操作的事件写入单个 Kafka 主题。 Kafka 主题的名称始终采用逻辑名称.数据库名称.集合名称的形式,其中逻辑名称是使用 topic.prefix 配置属性指定的连接器的逻辑名称,数据库名称是发生操作的数据库的名称,集合名称是受影响文档所在的 MongoDB 集合的名称。
例如,考虑一个 MongoDB 副本集,其库存数据库包含四个集合:产品、现有产品、客户和订单。如果监控此数据库的连接器被赋予了fulfillment的逻辑名称,那么连接器将生成关于这四个 Kafka 主题的事件:
- fulfillment.inventory.products
- fulfillment.inventory.products_on_hand
- fulfillment.inventory.customers
- fulfillment.inventory.orders
请注意,主题名称不包含副本集名称或分片名称。因此,对分片集合(其中每个分片包含集合文档的子集)的所有更改都将转到同一个 Kafka 主题。
您可以将 Kafka 设置为根据需要自动创建主题。如果没有,则必须在启动连接器之前使用 Kafka 管理工具创建主题。
十四、分区
MongoDB 连接器不会明确确定如何对事件主题进行分区。相反,它允许 Kafka 根据事件键确定如何对主题进行分区。您可以通过在 Kafka Connect 工作配置中定义 Partitioner 实现的名称来更改 Kafka 的分区逻辑。
Kafka 仅维护写入单个主题分区的事件的总顺序。按键对事件进行分区确实意味着具有相同键的所有事件始终进入同一分区。这可确保特定文档的所有事件始终完全有序。
十五、交易元数据
Debezium 可以生成代表事务元数据边界的事件并丰富变更数据事件消息。
Debezium 接收交易元数据的时间限制
Debezium 仅注册和接收部署连接器后发生的事务的元数据。部署连接器之前发生的事务的元数据不可用。
对于每笔交易的 BEGIN 和 END,Debezium 都会生成一个包含以下字段的事件:
状态:
- 开始或结束
ID:
- 唯一交易标识符的字符串表示形式。
event_count(对于 END 事件):
- 事务发出的事件总数。
data_collections(对于 END 事件):
- data_collection 和 event_count 对的数组,提供源自给定数据集合的更改所发出的事件数。
以下示例显示了一条典型消息:
{
“status”: “BEGIN”,
“id”: “1462833718356672513”,
“event_count”: null,
“data_collections”: null
}
{
“status”: “END”,
“id”: “1462833718356672513”,
“event_count”: 2,
“data_collections”: [
{
“data_collection”: “rs0.testDB.collectiona”,
“event_count”: 1
},
{
“data_collection”: “rs0.testDB.collectionb”,
“event_count”: 1
}
]
}
除非通过 topic.transaction 选项覆盖,否则事务事件将写入名为 <topic.prefix>.transaction 的主题。
十六、变更数据事件丰富
启用事务元数据后,数据消息信封将通过新的事务字段进行丰富。该字段以字段组合的形式提供有关每个事件的信息:
ID:
- 唯一交易标识符的字符串表示形式。
总订单数:
- 该事件在事务生成的所有事件中的绝对位置。
数据收集顺序:
- 事件在事务发出的所有事件中的每个数据收集位置。
以下是消息的示例:
{
“after”: “{”_id" : {“$numberLong” : “1004”},“first_name” : “Anne”,“last_name” : “Kretchmar”,“email” : “annek@noanswer.org”}",
“source”: {
…
},
“op”: “c”,
“ts_ms”: “1580390884335”,
“transaction”: {
“id”: “1462833718356672513”,
“total_order”: “1”,
“data_collection_order”: “1”
}
}
十七、数据变更事件
Debezium MongoDB 连接器为插入、更新或删除数据的每个文档级操作生成数据更改事件。每个事件都包含一个键和一个值。键和值的结构取决于更改的集合。
Debezium 和 Kafka Connect 是围绕连续的事件消息流而设计的。然而,这些事件的结构可能会随着时间的推移而改变,这对消费者来说可能很难处理。为了解决这个问题,每个事件都包含其内容的架构,或者,如果您使用架构注册表,则还包含消费者可用于从注册表获取架构的架构 ID。这使得每个事件都是独立的。
以下 JSON 框架显示了更改事件的基本四个部分。但是,您选择在应用程序中使用的 Kafka Connect 转换器的配置方式决定了这四个部分在更改事件中的表示。仅当您配置转换器来生成模式字段时,模式字段才会处于更改事件中。同样,仅当您配置转换器来生成事件键和事件负载时,事件键和事件负载才会出现在更改事件中。如果您使用 JSON 转换器并将其配置为生成所有四个基本更改事件部分,则更改事件具有以下结构:
{
“schema”: { 1
…
},
“payload”: { 2
…
},
“schema”: { 3
…
},
“payload”: { 4
…
},
}
表 7. 变更事件基本内容概述
选项 | 字段名称 | 描述 |
---|---|---|
1 | schema | 第一个架构字段是事件键的一部分。它指定了一个 Kafka Connect 架构,该架构描述了事件键的有效负载部分中的内容。换句话说,第一个模式字段描述了已更改的文档的键的结构。 |
2 | payload | 第一个有效负载字段是事件键的一部分。它具有先前架构字段描述的结构,并且包含已更改文档的键。 |
3 | schema | 第二个架构字段是事件值的一部分。它指定 Kafka Connect 架构,该架构描述事件值的有效负载部分中的内容。换句话说,第二个架构描述了已更改的文档的结构。通常,此模式包含嵌套模式。 |
4 | payload | 第二个有效负载字段是事件值的一部分。它具有先前架构字段描述的结构,并且包含已更改文档的实际数据。 |
默认情况下,连接器将事件记录流更改为名称与事件的原始集合相同的主题。
MongoDB 连接器确保所有 Kafka Connect 架构名称都遵循 Avro 架构名称格式。这意味着逻辑服务器名称必须以拉丁字母或下划线开头,即 a-z、A-Z 或 _。逻辑服务器名称中的每个剩余字符以及数据库和集合名称中的每个字符都必须是拉丁字母、数字或下划线,即 a-z、A-Z、0-9 或 _。如果存在无效字符,则将其替换为下划线字符。
如果逻辑服务器名称、数据库名称或集合名称包含无效字符,并且唯一区分名称的字符无效并用下划线替换,则可能会导致意外冲突。
十八、更改事件键
更改事件的键包含已更改文档的键的架构和已更改文档的实际键。对于给定的集合,模式及其相应的负载都包含单个 id 字段。该字段的值是文档的标识符,表示为从 MongoDB 扩展 JSON 序列化严格模式派生的字符串。
考虑一个逻辑名称为“fulfillment”的连接器、一个包含库存数据库的副本集以及一个包含如下文档的客户集合。
示例文档
{
“_id”: 1004,
“first_name”: “Anne”,
“last_name”: “Kretchmar”,
“email”: “annek@noanswer.org”
}
更改事件键示例
捕获客户集合更改的每个更改事件都具有相同的事件键架构。只要客户集合具有先前的定义,捕获客户集合更改的每个更改事件都具有以下关键结构。在 JSON 中,它看起来像这样:
{
“schema”: { 1
“type”: “struct”,
“name”: “fulfillment.inventory.customers.Key”, 2
“optional”: false, 3
“fields”: [ 4
{
“field”: “id”,
“type”: “string”,
“optional”: false
}
]
},
“payload”: { 5
“id”: “1004”
}
}
表 8. 更改事件键的说明
选项 | 字段 | 描述 |
---|---|---|
1 | schema | 密钥的架构部分指定 Kafka Connect 架构,该架构描述密钥的有效负载部分中的内容。 |
2 | fulfillment.inventory.customers.Key | 定义密钥有效负载结构的架构名称。此架构描述了已更改文档的键的结构。键架构名称的格式为连接器名称.数据库名称.集合名称.Key。在这个例子中:fulfillment 是生成此事件的连接器的名称。inventory 是包含已更改的集合的数据库。customers 是包含已更新文档的集合。 |
3 | optional | 指示事件键是否必须在其负载字段中包含值。在此示例中,需要密钥有效负载中的值。当文档没有密钥时,密钥有效负载字段中的值是可选的。 |
4 | fields | 指定负载中预期的每个字段,包括每个字段的名称、类型以及是否必需。 |
5 | payload | 包含为其生成此更改事件的文档的键。在此示例中,键包含一个字符串类型的 id 字段,其值为 1004。 |
此示例使用带有整数标识符的文档,但任何有效的 MongoDB 文档标识符都以相同的方式工作,包括文档标识符。对于文档标识符,事件键的 Payload.id 值是一个字符串,表示更新文档的原始 _id 字段,作为使用严格模式的 MongoDB 扩展 JSON 序列化。下表提供了如何表示不同类型的 _id 字段的示例。
表 9. 事件密钥有效负载中表示文档 _id 字段的示例
类型 | MongoDB _id Value | Key’s payload |
---|---|---|
Integer | 1234 | { “id” : “1234” } |
Float | 12.34 | { “id” : “12.34” } |
String | “1234” | { “id” : ““1234”” } |
Document | { “hi” : “kafka”, “nums” : [10.0, 100.0, 1000.0] } | { “id” : “{“hi” : “kafka”, “nums” : [10.0, 100.0, 1000.0]}” } |
ObjectId | ObjectId(“596e275826f08b2730779e1f”) | { “id” : “{”$oid" : “596e275826f08b2730779e1f”}" } |
Binary | BinData(“a2Fma2E=”,0) | { “id” : “{“KaTeX parse error: Expected group as argument to ‘"’ at position 9: binary" ̲: “a2Fma2E=”,…type” : “00”}” } |
十九、更改事件值
更改事件中的值比键稍微复杂一些。与键一样,值也具有模式部分和有效负载部分。模式部分包含描述有效负载部分的 Envelope 结构的模式,包括其嵌套字段。创建、更新或删除数据的操作的更改事件都具有带有信封结构的值有效负载。
考虑用于显示更改事件键示例的相同示例文档:
示例文档
{
“_id”: 1004,
“first_name”: “Anne”,
“last_name”: “Kretchmar”,
“email”: “annek@noanswer.org”
}
针对每种事件类型描述了对此文档的更改的更改事件的值部分:
- 创建事件
- 更新事件
- 删除事件
- 墓碑事件
二十、创建事件
以下示例显示连接器为在客户集合中创建数据的操作生成的更改事件的值部分:
{
“schema”: { 1
“type”: “struct”,
“fields”: [
{
“type”: “string”,
“optional”: true,
“name”: “io.debezium.data.Json”, 2
“version”: 1,
“field”: “after”
},
{
“type”: “string”,
“optional”: true,
“name”: “io.debezium.data.Json”,
“version”: 1,
“field”: “patch”
},
{
“type”: “struct”,
“fields”: [
{
“type”: “string”,
“optional”: false,
“field”: “version”
},
{
“type”: “string”,
“optional”: false,
“field”: “connector”
},
{
“type”: “string”,
“optional”: false,
自学几个月前端,为什么感觉什么都没学到??
这种现象在很多的初学者和自学前端的同学中是比较的常见的。
因为自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的迷茫的。
最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。
很多自学的朋友往往都是自己去找资料学习的,资料上有的或许就学到了,资料上没有的或许就没有学到。
这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。
但是真的是这样的吗?非也,因为很多人找的资料就是很基础的。学完了也就是掌握一点基础的东西。分享给你一份前端分析路线,你可以参考。
还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。
所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
se,
“field”: “version”
},
{
“type”: “string”,
“optional”: false,
“field”: “connector”
},
{
“type”: “string”,
“optional”: false,
自学几个月前端,为什么感觉什么都没学到??
这种现象在很多的初学者和自学前端的同学中是比较的常见的。
因为自学走的弯路是比较的多的,会踩很多的坑,学习的过程中是比较的迷茫的。
最重要的是,在学习的过程中,不知道每个部分该学哪些知识点,学到什么程度才算好,学了能做什么。
很多自学的朋友往往都是自己去找资料学习的,资料上有的或许就学到了,资料上没有的或许就没有学到。
这就会给人一个错误的信息就是,我把资料上的学完了,估计也-就差不多的了。
但是真的是这样的吗?非也,因为很多人找的资料就是很基础的。学完了也就是掌握一点基础的东西。分享给你一份前端分析路线,你可以参考。
还有很多的同学在学习的过程中一味的追求学的速度,很快速的刷视频,写了后面忘了前面,最后什么都没有学到,什么都知道,但是什么都不懂,要具体说,也说不出个所以然。
所以学习编程一定要注重实践操作,练习敲代码的时间一定要多余看视频的时间。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-13cwUA8w-1713659408352)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!