什么是 debezium?
debezium 是一系列分布式服务的集合,这些服务可以捕获数据库中行级别的更改,应用程序可以根据这些变化来做相应的处理。
debezium 在事务日志中记录提交给每个数据库表的所有行级别的更改,每个应用程序可以只读取自己感兴趣的事务日志,并按照更改时间发生的顺序查看所有的事件。
debezium 的名字是怎么来的?
该名称是“db”(多个数据库的缩写)和元素周期表中许多元素名称中使用的“-ium”后缀的组合。快说:“DBs-ium”。如果有帮助的话,我们把它念成“dee-BEE-zee-uhm”。
CDC是什么?
CDC,即 change data capture,指的是监视和捕获数据变化以便于其他应用能够对这些变化做出响应。数据仓库通常具有内置的 CDC 支持,因为当上游 OLTP 数据库中的数据发生更改时,数据仓库中的数据也需要及时更改。
而 debezium 本质上是一个现代的分布式开源 CDC 平台,支持监视各种数据库系统。
debezium 可以监视哪些数据库?
Debezium 的最新版本支持一下数据库:
- MySQL
- Oracle
- SQL Server
- PostgreSQL
- MongoDB
- Db2
- Cassandra
需要注意,如果需要监控PostgreSQL,需要再PostgreSQL服务器上安装一个logical decoding plugin
插件。
对于其他数据库的后续支持,需要查看 debezium 官方提供的路线图:https://debezium.io/roadmap/
debezium 有哪些使用场景?
debezium 的主要用于使应用程序在数据库中的数据发生变化的时候能够几乎立即做出响应。
- 应用程序可以对插入、更新、删除事件执行任何操作,比如使缓存失效、更新索引。
- 根据变更事件向一个或多个移动设备发送推送通知。
- 聚合数据库的更改,并为实体生成一系列修改。
- 存储数据库变更事件来作为审计日志。
- 将变更事件发送给Apache Flink或Kafka Streams来驱动流查询。
- 在微服务之间传播数据,例如采用发件箱模式。
为什么说 debezium 是一个分布式系统?
Debezium的架构是容忍错误和失败,而唯一有效的方法是使用分布式系统。Debezium将监视进程或连接器分布在多台机器上,这样,如果出现任何问题,连接器可以重新启动。事件被记录并在多台机器上复制,以最小化信息丢失的风险。
debezium 平台是什么样子的?
运行中的 debezium 系统由以下几个部分组成:
- Apache Kafka broker集群提供持久、复制和分区的事务日志。Kafka代理的数量在很大程度上取决于事件的数量、被监控的数据库表的数量以及使用事件的应用程序的数量。
- Debezium记录所有事件,应用程序从中消费所有事件。
- Kafka依赖于一个Zookeeper节点集群来管理每个 broker。
每个Debezium连接器监控一个数据库集群/服务器,并且连接器被配置和部署到Kafka Connect服务的集群中,以确保每个连接器始终运行,即使Kafka Connect服务实例离开并加入集群。每个Kafka Connect服务集群(又名组)都是独立的,因此组织内的每个组都可以管理自己的集群。
所有连接器都将它们的事件(和其他信息)记录到Apache Kafka, Kafka将每个表的事件保存、复制和分区到不同的主题中。多个Kafka Connect服务集群可以共享一个Kafka broker集群,但是Kafka broker的数量很大程度上取决于事件的数量,被监控的数据库表的数量,以及消耗事件的应用程序的数量。
应用程序直接连接到Kafka,并在适当的主题中使用事件。
debezium可以监控多少个数据库?
Debezium可以监控任意数量的数据库。可以部署到单个Kafka Connect服务集群的连接器数量取决于事件的数量和速率。然而,Debezium支持多个Kafka Connect服务集群,如果需要,也支持多个Kafka集群。
debezium 对于源数据库有什么影响?
debezium 对于要监视的数据库要求具有特定的配置和权限,大多数数据库必须先配置好,Debezium才能监控它们。例如,MySQL服务器必须配置为使用行级别的binlog格式;Debezium连接器必须配置正确的信息,包括数据库地址、用户名和密码,并且配置的用户具有相应的权限。有关详细信息,请参阅特定的连接器文档。
Debezium连接器不会在上游数据库中存储任何信息。但是,运行连接器可能会给源数据库带来额外的负载。
debezium 对于数据库的变更事件是如何保存的?
大多数debezium 的连接器将单个数据库表的所有变更事件记录到单个 topic 中。此外,topic 中的所有事件都是完全有序的。
比如,对于一个监视 MySQL 服务器的 MySQL 连接器来说,在名为server1.db1.table1
的 topic 中记录对于名为server1
的 MySQL服务器中database 名为db1
中数据表名为table1
的数据表的所有变动,同样,对于表 table2
来说,变动将记录在名为server1.db1.table2
的topic 中。
为什么记录的变更事件的内容这么大?
Debezium旨在监视上游数据库,并为每个行级更改生成一个或多个完整描述这些更改的相应事件。但是Debezium连接器是连续工作的,即使上游数据库中的表结构随时间变化,它的事件也必须有意义。如果消费者一次只需要处理一个事件,而不是跟踪整个事件流历史的状态,那么编写消费者也会容易得多。
这意味着每个事件都需要是完全自描述的:事件的键和值都包含一个 payload 和一个 schema。 payload 描述事件信息,而 schema 描述事件中信息的结构。消费应用程序可以处理每个事件,使用schema来理解该事件中的信息结构,然后正确处理事件的payload。这里事件中的 schema可以理解为监听的数据表的表结构,payload 可以理解为数据表的数据。
事实上,只要监听的数据表的表结构不变,事件中的schema就是相同的。所以消费事件的应用程序可以基于这一点进行优化,只有当数据表 schema发生更改时,消费端再来更新自己的 schema 信息即可。
同时,Kafka Connect 序列化连接器的事件并记录在Kafka中。JSON转换器非常通用,也非常简单,但它只能序列化整个事件信息。因此,用JSON表示的事件确实冗长而庞大。
但是,还有一种替代方法:使用schema注册表。这样,实际的schema信息由注册中心管理,而实际的更改事件只包含注册中心中相应模式的id。这导致发送到Kafka的事件的更有效的表示。模式注册表可以用于不同的格式,如JSON或Avro。利用Avro作为消息格式还有一个额外的优点,即有效负载被序列化成非常紧凑的二进制形式。
使用这种方法,Kafka Connect转换器和模式注册表一起工作,跟踪每个模式随时间的历史。同时,在消费者中,相同的转换器解码事件的压缩二进制形式,读取该消息使用的模式版本的标识符(如果还没有看到模式版本的话),从模式注册中心下载模式,最后使用该模式解码事件的有效负载。同样,按顺序排列的许多事件将共享相同的模式。
如何使用 schema 注册表?
模式注册表的选项包括Apicurio API和模式注册表以及Confluent模式注册表。两者都带有转换器,用于在注册表中存储JSON和Avro模式或者从注册表中获取JSON和Avro模式。
如果要将Debezium连接器部署到Kafka Connect,只需确保注册表中的转换器jar可用,并配置使用正确的转换器。例如,您需要将转换器指向Apicurio Schema Registry。然后,只需将Debezium连接器(或者实际上,任何其他Kafka Connect连接器)部署到您的worker服务。有关如何将Avro转换器与Api一起使用的详细说明,请参阅Avro序列化。
GitHub上的教程示例详细展示了如何在Debezium中使用模式注册表和附带的转换器。
我们的Kafka Connect的Docker镜像包括Avro转换器作为一个选项。
当应用程序停止或崩溃时会发生什么?
为了消费数据库的变更事件,应用程序创建一个Kafka消费者,它将连接到Kafka代理,并消费与该数据库关联的topic的所有事件。消费者被配置为定期记录其在每个topic中的位置(即偏移量)。
当应用程序正常停止并关闭使用者时,使用者将记录每个topic中最后一个事件的偏移量。当应用程序稍后重新启动时,使用者将查找这些偏移量,并开始读取每个topic中的下一个事件。因此,在正常操作场景下,应用程序对于事件的处理满足exactly once
语义,即对于每个 topic 的事件只会处理一次。
如果应用程序意外崩溃,那么在重新启动应用程序时,应用程序的使用者将查找每个topic的最后记录偏移量,并从每个topic的最后偏移量开始消费事件。在大多数情况下,应用程序将看到它在崩溃之前看到的一些相同的事件(但在它记录偏移量之后),然后是它还没有看到的事件。因此,在意外崩溃的情况下,应用程序对于事件的处理满足at least once
语句,即对于每个事件至少处理一次。虽然应用程序可以通过更频繁地记录偏移量来减少重复处理的事件数量,但是这样做会对客户端的性能和吞吐量产生负面影响,只要可以保证对于事件的处理事幂等的,at least once
的语义也可以满足要求。
请注意,Kafka消费者可以配置为连接并开始读取每个topic中最近的偏移量,这对于只需要消费最新的数据这种场景来说是合理的。
当Debezium停止或崩溃时会发生什么?
Debezium的行为取决于哪些组件被停止或崩溃。如果有足够的Kafka broker停止或崩溃,使得每个主题分区的同步副本数量少于最小数量,那么写入这些主题的连接器和从这些主题读取的消费应用程序将会阻塞,直到Kafka代理可以重新启动或新的broker上线。因此,同步副本的最小数量对可用性有非常大的影响,出于一致性的原因,至少应该是1(如果不是3)。
Kafka Connect服务配置为定期记录每个连接器的位置和偏移量。如果集群中的一个Kafka Connect服务实例被优雅地停止,那么在该进程中运行的所有连接器将被优雅地停止(意味着所有位置和偏移量将被记录),并且这些相同的连接器将在同一集群中的其他Kafka Connect服务实例上重新启动。当这些连接器重新启动时,它们将继续准确地记录事件,而不会记录重复事件。
当Kafka Connect服务集群中运行的一个连接器被优雅地停止时,它将完成当前的工作,并记录Kafka中最新的位置和偏移量。消费topic中消息的下游应用程序只需等待,直到添加新事件。
如果集群中的任何Kafka Connect服务实例意外崩溃,那么在崩溃进程中运行的所有连接器将在同一集群中的其他Kafka Connect服务实例上重新启动。但是,当这些连接器重新启动时,它们将从连接器崩溃前最后记录的位置/偏移量开始从数据库记录事件。这意味着新重新启动的连接器可能会记录一些在崩溃之前记录的相同事件,并且这些重复的事件对于下游消费应用程序始终是可见的。
当被监听的数据库停止或崩溃时会发生什么?
当Debezium监听的数据库服务器停止或崩溃时,Debezium连接器可能会尝试重新建立通信。Debezium定期在Kafka中记录连接器的位置和偏移量,因此一旦连接器建立通信,连接器应该继续从最后记录的位置和偏移量读取。
为什么消费应用程序必须能够处理重复事件?
当所有系统都正常运行或部分或全部系统优雅地关闭时,消费端应用程序对于每个事件只会处理一次。然而,当出现问题时,消费端应用程序可能重复处理某些事件。
kafka是什么?
Apache Kafka是一个快速、可扩展、持久和分布式的消息传递系统,它将所有消息记录在复制、分区和完全有序的事务日志中。消费者跟踪他们在日志中的位置,并且可以独立于所有其他消费者控制这个位置。这意味着一些消费者可以从日志的最开始开始,而另一些消费者可以跟上最近记录的消息。Kafka作为一个动态的代理集群运行。每个日志分区被复制到多个代理中,这样,如果任何代理失败,集群仍然拥有该分区的多个副本。
Debezium连接器将所有事件记录到Kafka集群,应用程序通过Kafka消费这些事件。
kafka connect 是什么?
Kafka Connect是一个框架,用于在Apache Kafka和其他系统之间进行可扩展和可靠的数据流。它是Kafka社区的新成员,它使得定义将大量数据移入和移出Kafka的连接器变得简单,而框架则完成了正确记录连接器偏移量的大部分底层工作。Kafka Connect服务有一个RESTful API来管理和部署连接器;该服务可以集群化,并将在集群中自动分布连接器,确保连接器始终运行。
Debezium 使用 Kafka Connect框架。Debezium的所有连接器都是Kafka Connector源连接器,因此它们可以使用Kafka Connect服务进行部署和管理。