Debezium是一个开源项目,为更改数据捕获(CDC)提供了低延迟的数据流平台。您设置并配置Debezium来监视数据库,然后您的应用程序会使用对数据库进行的每个行级更改的事件。仅显示已提交的更改,因此您的应用程序不必担心事务或回滚的更改。Debezium提供了所有变更事件的单一模型,因此您的应用程序不必担心每种数据库管理系统的复杂性。此外,由于Debezium会在持久的复制日志中记录数据更改的历史记录,因此您的应用程序可以随时停止和重新启动,并且能够使用未运行时错过的所有事件,
监视数据库并在数据更改时得到通知总是很复杂。关系数据库触发器可能有用,但特定于每个数据库,并且通常仅限于更新同一数据库内的状态(不与外部进程进行通信)。一些数据库提供用于监视更改的API或框架,但是没有标准,因此每个数据库的方法都不相同,并且需要大量知识丰富且专门的代码。确保将所有更改以相同的顺序显示和处理,同时对数据库的影响最小,这仍然是非常具有挑战性的。
Debezium提供了可以为您完成此工作的模块。一些模块是通用的,可以与多个数据库管理系统一起使用,但是在功能和性能上也有一些限制。其他模块是为特定的数据库管理系统量身定制的,因此它们通常功能更强大,并且可以利用系统的特定功能。
基本架构
Debezium是一个变更数据捕获(CDC)平台,通过重用Kafka和Kafka Connect来实现其耐用性,可靠性和容错性。部署到Kafka Connect分布式,可伸缩,容错服务的每个连接器都监视单个上游数据库服务器,捕获所有更改并将它们记录在一个或多个Kafka主题(通常每个数据库表一个主题)中。Kafka确保所有这些数据更改事件都得到复制和完全排序,并允许许多客户端独立使用这些相同的数据更改事件,而对上游系统的影响很小。此外,客户端可以随时停止消费,并且在重新启动客户端时,它们会从中断的位置继续恢复。每个客户都可以确定是否希望一次或一次最少地交付所有数据更改事件,
不需要或不需要这种级别的容错,性能,可伸缩性和可靠性的应用程序可以改用Debezium的嵌入式连接器引擎在应用程序空间内直接运行连接器。他们仍然想要相同的数据更改事件,但是更喜欢让连接器将它们直接发送到应用程序,而不是将其持久保存在Kafka中。
常见用例
在许多情况下,Debezium可能都是非常有价值的,但是在这里,我们仅概述其中一些较为常见的情况。
缓存无效
条目的记录更改或删除后,将自动使缓存中的条目无效。如果缓存在单独的进程(例如Redis,Memcache,Infinispan等)中运行,则可以将简单的缓存失效逻辑放入单独的进程或服务中,从而简化主应用程序。在某些情况下,可以使逻辑稍微复杂一些,并且可以使用更改事件中的更新数据来更新受影响的缓存条目。
简化整体应用
许多应用程序都会更新数据库,然后在提交更改后执行其他工作:更新搜索索引,更新缓存,发送通知,运行业务逻辑等。由于应用程序正在向多个系统进行写操作,因此通常称为“双重写入”在单笔交易之外。如果应用程序在提交之后但在执行某些/所有其他更新之前崩溃,则不仅应用程序逻辑复杂且难以维护,而且双重写入还可能会丢失数据或使各种系统不一致。使用更改数据捕获,当将数据提交到原始数据库中时,可以在单独的线程或单独的进程/服务中执行这些其他活动。这种方法更能容忍失败,不会错过事件,扩展性更好,
共享数据库
当多个应用程序共享一个数据库时,一个应用程序了解另一应用程序提交的更改通常并不容易。一种方法是使用消息总线,尽管非事务性消息总线会遇到上述“双重写入”问题。但是,对于Debezium来说,这变得非常简单:每个应用程序都可以监视数据库并对更改做出反应。
资料整合
数据通常存储在多个位置,尤其是当数据用于不同目的并且格式略有不同时。保持多个系统同步可能具有挑战性,但是可以使用Debezium和简单的事件处理逻辑快速实现简单的ETL类型的解决方案。
CQRS
该命令查询责任分离(CQRS)架构模式用来更新和一个或多个其他数据模型读取一个数据模型。当更改记录在更新侧时,这些更改将被处理并用于更新各种读取表示形式。结果,CQRS应用程序通常会更复杂,尤其是当它们需要确保可靠且完全有序的处理时。Debezium和CDC可以使此操作更容易实现:写操作被正常记录,但是Debezium捕获了持久性,完全有序流中的那些更改,这些流由异步更新只读视图的服务使用。写侧表可以表示面向领域的实体,也可以将CQRS与事件源配对使用 写侧表是命令的仅附加事件日志。
构建Debezium
需要以下软件才能使用Debezium代码库并在本地进行构建:
- Git 2.2.1或更高版本
- JDK 8或OpenJDK 8
- Maven 3.2.1或更高版本
- Docker Engine 1.9或更高版本
请参阅上面的链接以获取平台上的安装说明。您可以验证版本是否已安装并正在运行:
$ git --version
$ javac -version
$ mvn -version
$ docker --version
为什么选择Docker?
许多开源软件项目都使用Git,Java和Maven,但很少要求使用Docker。Debezium旨在与许多外部系统进行对话,例如各种数据库和服务,并且我们的集成测试证明Debezium可以正确执行此操作。但是Debezium的构建系统并没有期望您在本地安装所有这些软件系统,而是使用Docker自动下载或创建必要的映像并启动每个系统的容器。然后,集成测试可以使用这些服务并验证Debezium的行为是否符合预期,并且在集成测试完成时,Debezium的构建将自动停止其启动的所有容器。
Debezium还具有一些不是用Java编写的模块,因此在目标操作系统上必须使用它们。Docker让我们的构建使用带有目标操作系统和所有必要开发工具的映像来执行此操作。
使用Docker具有以下优点:
- 您不必在本地计算机上安装,配置和运行每个外部服务的特定版本,也不必在本地网络上访问它们。即使您这样做,Debezium的构建也不会使用它们。
- 我们可以测试外部服务的多个版本。每个模块都可以启动所需的任何容器,因此不同的模块可以轻松使用不同版本的服务。
- 每个人都可以在本地运行完整的构建。您不必依赖在设置了所有必需服务的环境中运行构建的远程连续集成服务器。
- 所有构建都是一致的。当多个开发人员都构建相同的代码库时,只要使用相同或等效的JDK,Maven和Docker版本,他们应该会看到完全相同的结果。这是因为容器将在相同的操作系统上运行相同版本的服务。另外,所有测试都旨在连接到容器中运行的系统,因此没有人需要摆弄特定于其本地环境的连接属性或自定义配置。
- 无需清理服务,即使这些服务在本地修改和存储数据也是如此。Docker 映像已缓存,因此重复使用它们来启动容器是快速且一致的。但是,Docker 容器永远不会被重用:它们始终以原始的初始状态启动,并在关闭时被丢弃。集成测试依赖于容器,因此清理是自动进行的。
配置您的Docker环境
Docker Maven插件将通过检查以下环境变量来解析Docker主机:
export DOCKER_HOST=tcp://10.1.2.2:2376
export DOCKER_CERT_PATH=/path/to/cdk/.vagrant/machines/default/virtualbox/.docker
export DOCKER_TLS_VERIFY=1
如果使用Docker Machine或类似的东西,这些可以自动设置。
构建代码
首先通过克隆Git存储库获取代码:
$ git clone https://github.com/debezium/debezium.git
$ cd debezium
然后使用Maven构建代码:
$ mvn clean install
构建开始,并将几个Docker容器用于不同的DBMS。请注意,如果未运行或未配置Docker,则可能会收到一个不可思议的错误-如果是这种情况,请始终通过docker ps列出运行容器来验证Docker是否正在运行。
Docker没有在本地运行吗?
您可以使用以下命令跳过集成测试和docker-builds:
$ mvn clean install -DskipITs
使用wal2json逻辑解码插件运行Postgres连接器的测试
Postgres连接器支持两个逻辑解码插件,用于将更改从DB服务器流式传输到连接器:decodebufs(默认)和wal2json。要使用wal2json运行PG连接器的集成测试,请启用“ wal2json-decoder”构建配置文件:
$ mvn clean install -pl :debezium-connector-postgres -Pwal2json-decoder
使用wal2json插件时,一些测试目前无法通过。查找对其中定义的类型的引用以io.debezium.connector.postgresql.DecoderDifferences找到这些测试。
针对外部数据库(例如Amazon RDS)运行Postgres连接器的测试
请注意,如果要针对非RDS集群进行测试,则此测试必须是超级用户,不仅具有超级用户的replication权限,而且还具有登录中的all数据库的权限pg_hba.conf。它还要求postgis目标服务器上的软件包可用,以便通过某些测试。
$ mvn clean install -pl debezium-connector-postgres -Pwal2json-decoder \
-Ddocker.skip.build=true -Ddocker.skip.run=true -Dpostgres.host=<your PG host> \
-Dpostgres.user=<your user> -Dpostgres.password=<your password> \
-Ddebezium.test.records.waittime=10
根据需要调整超时值。
有关在RDS上设置要测试的数据库的详细信息,请参见Amazon RDS上的PostgreSQL。