Debezium 博客
Debezium 社区的朋友们,新年快乐!
祝愿你们所有的努力都取得成功,数据保持一致,最重要的是,大家都平安健康。2020 年已经过去,我想回顾一下今年 Debezium 发生的一切。
首先,为各位统计爱好者们准备了一些数据和数字。
在过去的五年里,Debezium 已成为各种数据库变更数据捕获(CDC)的领先开源解决方案。来自各行各业的用户使用 Debezium 来实现数据从操作数据库复制到数据仓库、更新缓存和搜索索引、通过 Kafka Streams 或 Apache Flink 驱动流式查询、同步微服务之间的数据等多种用例。
在与 Debezium 用户交流时,我们通常会收到关于 Debezium 提供的应用范围及其灵活性的良好反馈:例如,每个连接器都可以根据您的具体需求进行各种配置和微调。大量的指标提供了对运行中的 Debezium 连接器状态的深入了解,从而可以安全地在拥有数千个连接器的巨大安装环境中运行 CDC 管道。
然而,这一切都伴随着一定的学习曲线:新接触 Debezium 的用户需要了解不同的选项和设置,并学习在生产环境中运行 Debezium 的最佳实践。因此,我们一直在探索如何进一步改善 Debezium 的用户体验,让人们能够更轻松地设置和操作其连接器。
当您使用Kafka Connect分布式模式时,您可能会发现一旦启动Kafka Connect,就会自动创建一些与Kafka Connect相关的内部主题。
$ kafka-topics.sh --bootstrap-server $HOSTNAME:9092 --list
connect_configs
connect_offsets
connect_statuses 这是由Kafka Connect自动为您完成的,使用了合理的、定制化的默认主题配置,以满足这些内部主题的需求。
当您启动一个Debezium连接器时,捕获事件的主题将由Kafka代理根据默认(可能经过定制)的代理配置创建,前提是代理配置中启用了auto.create.topics.enable = true。
auto.create.topics.enable = true
default.replication.factor = 1
num.partitions = 1
compression.type = producer
log.cleanup.policy = delete
log.retention.ms = 604800000 ## 7 days 但是,在生产环境中,当您使用Debezium和Kafka时,通常会选择禁用Kafka的主题自动创建功能(设置auto.create.topics.enable = false),或者您希望连接器主题的配置与默认值不同。在这种情况下,您必须提前为Debezium的捕获数据源创建主题。
但是,有个好消息!从Kafka Connect版本2.6.0开始,由于KIP-158的实现,可以通过Kafka Connect实现可定制的主题创建,这使得这一过程自动化成为可能。
使用 Debezium 设置变更数据捕获 (CDC) 流水线通常只是配置问题,无需编程。拥有自动化测试来验证您的 CDC 设置,确保一切配置正确并且您的 Debezium 连接器按预期设置,仍然是一个非常好的主意。
需要考虑配置的两个主要组件是:
-
源数据库:必须进行设置,以便 Debezium 可以连接到它并检索变更事件;具体细节取决于数据库,例如,对于 MySQL,binlog 必须处于“row”模式,对于 Postgres,必须安装支持的逻辑解码插件之一,等等。
-
Debezium 连接器:必须使用正确的数据库主机和凭据进行配置,可能使用 SSL,应用表和列过滤器,可能应用一个或多个单消息转换(SMTs)等。
我们为与 Db2 的使用开发了一个 Debezium 连接器,该连接器现已作为 Debezium 孵化器的一部分可用。在这里,我们描述了变更数据捕获 (CDC) 的用例、Db2 生态系统中已有的各种方法,以及我们如何转向 Debezium。此外,我们还论证了我们实现 Db2 Debezium 连接器所采取的方法。
本文将深入探讨事件溯源、CQRS(命令查询责任分离)、CDC(变更数据捕获)和 Outbox 模式。将清晰地阐述这些解决方案的价值。此外,还将详细解释两种不同的设计,并分析它们的优缺点。
那么,为什么所有这些解决方案都很重要呢?它们很重要,因为许多团队正在构建微服务并将数据分布在多个数据存储中。一个微服务系统可能涉及关系数据库、对象存储、内存缓存,甚至可搜索的数据索引。数据很容易丢失、不同步甚至损坏,从而对关键任务系统造成灾难性后果。
对于许多组织来说,有助于避免这些严重问题的解决方案至关重要。不幸的是,许多重要的解决方案有些难以理解;事件溯源、CQRS、CDC 和 Outbox 也不例外。请将这些解决方案视为学习和理解如何将其应用于您特定用例的机会。
正如您将在本文结尾处发现的那样,我将建议其中四个解决方案中有三个具有很高的价值,而另一个应尽可能避免使用,除非在极少数情况下。本文提供的建议应根据您的具体需求进行评估,因为在某些情况下,这四个解决方案都不适合。
Outbox,就像我电子邮件客户端中的那个文件夹一样?不,不完全是,但有一些相似之处!
Outbox 这个术语描述了一种模式,它允许独立组件或服务执行读取您自己的写入语义,同时在组件或服务边界之间提供对这些写入的可靠、最终一致的视图。
您可以在我们的博客文章《使用 Outbox 模式实现可靠的微服务数据交换》中阅读有关 Outbox 模式及其在微服务中的应用的更多信息。
那么,Outbox 事件路由器到底是什么?
作为近期 使用变更数据捕获和流处理构建审计日志 博客文章的后续,我们希望通过管理功能扩展此示例,使其能够捕获和修复任何缺失的事务数据。
在上述博客文章中,有一个日志增强服务,用于将“Vegetable”数据库表中插入或更新的数据与事务上下文数据(例如
-
事务 ID
-
执行操作的用户名
-
实际更改背后的用例,例如“创建蔬菜”
只要所有更改都通过蔬菜服务进行,这一切都能很好地工作。但情况总是如此吗?
那么维护活动或直接在数据库级别执行的迁移脚本呢?仍然存在大量此类活动,无论是故意的,还是因为这是我们正在努力改变的老习惯……
让我们谈谈 TOAST。吐司?不,TOAST!
那是什么?TOAST (The Oversized-Attribute Storage Technique,超大属性存储技术) 是 Postgres 中的一种机制,它将大型列值存储在多个物理行中,从而绕过了 8 KB 的页面大小限制。
通常,TOAST 存储对用户是透明的,所以您真的不必关心它。但是有一个例外:如果表行已更改,则使用 TOAST 机制存储的任何*未更改*值都不会包含在 Debezium 从数据库收到的消息中,除非它们是表复制身份的一部分。因此,这种未更改的 TOAST 列值将不会包含在发送到 Apache Kafka 的 Debezium 数据变更事件中。在本文中,我们将讨论处理这种情况的不同策略。
业务应用程序通常需要维护某种形式的审计日志,即应用程序数据所有更改的持久化跟踪。如果仔细看,带有 Debezium 数据更改事件的 Kafka 主题与之非常相似:它源自数据库事务日志,描述了应用程序记录的所有更改。所缺少的只是一些元数据:数据为何、何时以及由谁更改?在本博文中,我们将探讨如何通过变更数据捕获 (CDC) 提供和公开这些元数据,以及如何使用流处理来丰富实际的数据更改事件以包含此类元数据。
这是 Apache Pulsar PMC 成员兼 Comitter 翟嘉(Jia Zhai)的客座博文。
Debezium 是一个开源的变更数据捕获(CDC)项目。它基于 Apache Kafka Connect 构建,并支持多种数据库,如 MySQL、MongoDB、PostgreSQL、Oracle 和 SQL Server。 Apache Pulsar 包含一套基于 Pulsar IO 框架的 内置连接器,它与 Apache Kafka Connect 是对应的。
从 2.3.0 版本开始,Pulsar IO 开箱即用地支持 Debezium 源连接器,因此您可以利用 Debezium 将数据库中的变更流式传输到 Apache Pulsar。本教程将引导您完成 Debezium MySQL 连接器与 Pulsar IO 的设置。
作为其业务逻辑的一部分,微服务通常不仅需要更新自己的本地数据存储,还需要通知其他服务有关发生的数据更改。Outbox 模式描述了一种安全一致地执行这两项任务的方法;它为源服务提供即时的“读你自己的写”语义,同时提供跨服务边界的可靠的、最终一致的数据交换。
Hibernate ORM / JPA 的二级缓存是一种经过验证且高效的提高应用程序性能的方法:缓存只读或很少修改的实体可避免数据库往返,从而提高应用程序的响应时间。
与一级缓存不同,二级缓存与会话工厂(或 JPA 中的实体管理器工厂)相关联,因此其内容在事务和并发会话之间共享。理所当然,如果缓存的实体被修改,相应的缓存条目也必须被更新(或从缓存中清除)。只要数据更改是通过 Hibernate ORM 完成的,就无需担心:ORM 会自动更新缓存。
然而,当绕过应用程序(例如,直接修改数据库中的记录)时,事情就会变得棘手。此时,Hibernate ORM 无法知道缓存的数据已过时,因此有必要显式使受影响的条目失效。一种常见的做法是提供一些管理员功能,允许清除应用程序的缓存。为了使其正常工作,切勿忘记调用该失效功能至关重要,否则应用程序将继续使用过时缓存的数据。
在下文中,我们将探讨一种缓存失效的替代方法,该方法可以可靠且完全自动化地工作:通过利用 Debezium 及其变更数据捕获(CDC)功能,您可以直接在数据库中跟踪数据更改并对已应用的任何更改做出反应。这允许近实时地使受影响的缓存条目失效,而不会因遗漏更改而导致过时数据的风险。如果某个条目已从缓存中移除,Hibernate ORM 将在下次请求时从数据库加载该实体的最新版本。
在数据更改后更新外部全文搜索索引(例如 Elasticsearch)是变更数据捕获 (CDC) 非常流行的用例。
正如我们在一段时间前的 博客文章 中讨论过的,Debezium 的 CDC 源连接器与 Confluent 的 Elasticsearch 接收器连接器 的结合,可以轻松地在 MySQL、Postgres 等数据库中捕获数据更改,并近乎实时地将它们推送到 Elasticsearch。这导致源数据库中的表与 Elasticsearch 中的相应搜索索引之间存在 1:1 的关系,对于许多用例来说是完全可以的。
但是,如果您想将整个聚合数据放入单个索引中,情况会更具挑战性。例如,一个客户及其所有地址;这些通常存储在关系型数据库的两个单独的表中,通过外键连接,而您只想在 Elasticsearch 中有一个索引,其中包含具有嵌入式地址的客户文档,从而允许您根据地址高效地搜索客户。
继我们最近讨论的 基于 KStreams 的解决方案 之后,我们想在本文中介绍一个通过应用程序层驱动物化此类聚合视图的替代方案。
大多数情况下,Debezium 用于将数据更改流式传输到 Apache Kafka。但如果您使用的是其他流式传输平台,例如 Apache Pulsar,或者云原生解决方案,例如 Amazon Kinesis、Azure Event Hubs 等等呢?您仍然可以受益于 Debezium 强大的变更数据捕获 (CDC) 功能,并从 MySQL、Postgres、SQL Server 等数据库中摄取更改吗?
事实证明,只需一点粘合代码,就可以做到!接下来,我们将讨论如何使用 Debezium 捕获 MySQL 数据库中的更改,并将更改事件流式传输到 Kinesis,这是一个在 Amazon 云中提供的完全托管的数据流服务。
昨天,我有机会向 达姆施塔特 Java 用户组 介绍了 Debezium 和变更数据捕获 (CDC) 的理念。这是一个很棒的夜晚,有很多有趣的讨论和问题。其中一个问题是:使用像 Debezium 这样的基于日志的变更数据捕获工具,相比于仅仅轮询更新记录,有什么优势?
那么,这两种方法有什么区别呢?通过轮询(或查询)的 CDC,您会反复运行查询(例如通过 JDBC)来检索要捕获的表中的任何新插入或更新的行。相反,基于日志的 CDC 通过响应数据库日志文件(例如 MySQL 的 binlog 或 MongoDB 的 op log)中的任何更改来工作。
由于这个问题已经不是第一次出现了,我决定在这里的博客上提供一个更详尽的回答。这样,如果将来再次出现这个问题,我就可以引用这篇帖子了 :)
那么,废话不多说,以下是我列出的基于日志的 CDC 相对于基于轮询的方法的五大优势。