原文地址: https://debezium.io/blog/2020/03/05/db2-cdc-approaches/
欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯.
运行 Db2 更改数据捕获的方法
2020 年 3 月 5 日 作者: Luis Garcés-Erice、Sean Rooney、Peter Urbanetz
数据库 讨论
我们开发了一个可与Db2配合使用的 Debezium 连接器,该连接器现已作为 Debezium 孵化器的一部分提供。在这里,我们描述了变更数据捕获 (CDC) 的用例、Db2 生态中已经存在的各种方法,以及我们如何来到 Debezium。此外,我们还激励了用于实现 Db2 Debezium 连接器的方法。
背景:将数据引入 Datalake
2016 年,IBM 开始致力于构建一个可以摄取、管理和处理 IBM 企业数据的单一平台:认知企业数据平台 ( CEDP )。IBM 研究中心是该项目的主要贡献者之一。基本活动之一是将数据从地理上分散的数据中心引入平台。数据湖的摄取使用了多种技术。
图片来自于原文
图 1.CEDP 逻辑架构
企业数据的很大一部分收集在现有数据仓库和数据集市中的关系数据库中。这些通常是生产系统,其主要用途是作为营销、销售、人力资源等的“记录系统”。由于这些系统是由 IBM 为 IBM 运行的系统,因此它们主要是 IBM Db2 的某些变体,这并不奇怪。
高效地从 Db2 获取数据
数据被摄取到 Datalake 内的不可变着陆区中。该登陆区作为 HDFS 实例实现。流数据(例如新闻)使用 Kafka 从源移出,然后使用适当的连接器写入 HDFS。
我们的关键设计目标之一是自动化。每天会提取来自 200 多个不同来源的 5,000 多个关系数据库表。为了扩展数据处理平台——除了允许数据所有者将数据引入平台的治理流程之外——摄取本身必须是自助服务。
最初,关系数据总是使用Sqoop从源批量加载。提供 REST 接口,以便数据所有者可以配置何时应移动数据,例如定期移动、触发事件等。Sqoop 摄取是一组分布式任务,每个任务都使用 JDBC 连接来读取关系数据库的一部分。数据库表,生成基于文件的数据表示,例如Parquet,然后将其存储在 HDFS 上。使用Sqoop,我们可以完全刷新数据,或者追加数据,但是我们不能增量地修改数据。
从实际角度来看,这限制了数据更新的周期。一些较大的表代表数十 GB 的压缩 Parquet。虽然 Sqoop 允许对同一个表并行运行许多任务,但瓶颈通常是跨 WAN 的网络和/或源数据库系统本身的速率控制。通常在任何特定的一天只修改表的一小部分,这意味着不必要地发送大量数据。
为了解决这些问题,我们引入了使用变更数据捕获 (CDC) 来跨 WAN 移动数据。在 CDC 模式下将数据摄取到专为从未修改的文件而设计的存储系统中是有问题的。虽然Deltalakes或Hive 3.0等最近的一些工作已经开始将增量更改引入 Hadoop 生态系统,但这些工作还不够成熟,无法满足我们的需求。
作为替代方案,我们使用关系数据库放置区的概念,数据所有者可以在其中实例化其数据库的影子,然后将其摄取到 HDFS 中。由于 Drop Zone 和 Landing Zone 位于同一数据中心,并且数据摄取是一项高度并行化的任务,因此大型表的实际摄取通常比从源传输数据快几个数量级。
数据所有者可以使用他们喜欢的任何工具将数据移动到放置区。特别是,他们可以将对通过 CDC 获得的数据进行更改。
CDC 系统几乎和关系数据库本身一样古老。通常,它们是为了备份或故障恢复而设计的,并且是供数据库管理员使用的。
Db2 有着悠久的历史,已有 40 多年的历史,并且运行在多种操作系统上,包括 zOS、AIX、Linux 和 Windows。它为 CDC 开发了一大批不同的工具,用于不同的环境。我们开始探索 IBM 的SQL Replication的使用。一旦管理员将表置于 CDC 模式,捕获代理就会启动,从事务日志中读取对这些表所做的更改。这些更改存储在专用的 CDC 表中。在远程数据库中,应用代理会定期读取这些 CDC 表中的更改并更新影子表。
虽然从概念上讲这在实践中非常简单,但由于以下原因很难实现自动化:
源和接收器紧密耦合,因此同一个表无法轻松复制到多个不同的目标数据库系统。
如果源系统已经在表上使用复制(例如出于备份目的),则我们无法使用此方法复制到 Datalake。
需要对源进行提升的权限。数据所有者向 Sqoop 授予对其系统的读取权限,但向管理员授予权限会带来合规性问题。
水槽需要提升权限。为简单起见,我们的 Drop Zone 是一个单一的 Db2 系统,其中包含每个数据源的数据库实例。允许数据所有者将 SQL 复制设置到放置区将允许他们访问彼此的实例,这违反了合规性。
这些工具是为系统管理员设计的,因此,粗心的人会遇到很多问题。例如,在选择各种参数时必须小心,例如:事务日志必须处于允许 CDC 的模式、上次备份的时间、数据库是面向行还是面向列等。
它是 Db2 特定的解决方案;尽管大多数关系数据源是 Db2,但我们也有 Netezza、MySQL 和 SQL Server 源。
我们在实践中发现,上述组合意味着允许数据所有者使用 IBM SQL Replication 作为 Datalake 的 CDC 机制是不切实际的。
IBM 提供了另一组数据复制工具,称为 IBM InfoSphere Data Replication ( IIDR)。它作为与 Db2 不同的产品出售。IIDR 不是 Db2 特定的解决方案,适用于各种关系数据库以及非关系数据存储系统(例如文件系统)。本质上,IIDR 有源代理和汇代理。源代理和接收器代理在目标系统处或附近运行。源代理读取更改并通过各种协议(包括 TCP 套接字、MQ、共享文件等)将它们传播到接收器代理。源代理和接收器代理通过称为访问服务器的实体进行配置,通过该实体将源连接到接收器并指定要捕获的表。访问服务器本身通常由系统管理员通过图形用户界面进行控制。
例如,我们可以拥有一个 Db2 源代理和一个 IIDR Kafka 接收器代理,其行为类似于标准 Apache Kafka Connect 源连接器,即将更改事件写入 Kafka 主题。初始记录是更新插入消息(刷新阶段),后续更改将作为一系列更新插入/删除消息(镜像阶段)进行传播。
IIDR 使系统更加松散耦合,并且减少了 Db2 的特定性。然而,自动化仍然不简单。本质上,我们需要能够允许数据所有者通过 REST 调用指定源数据库系统和要复制的表,并在 Kubernetes 集群上自动配置和部署必要的代理和访问服务器。由于我们无法在源系统本身上运行,因此我们对远程 Db2 系统进行编目,使其看起来像是本地系统,并在其上运行代理。
IIDR 假设代理在与关系数据库系统相同的硬件架构上运行。IIDR 代理使用低级别Db2 API来读取事务日志。我们的许多源系统都在 AIX/PowerPC 上运行,而部署代理的 Kubernetes 平台在 Linux/Intel 上运行。这会导致字节序兼容性问题。
这种方法有两个限制:
IIDR 旨在由系统管理员监控和管理。尝试通过解析这些日志的脚本来捕获管理员的操作和响应,并尝试对 IIDR 中的故障做出反应,只会很脆弱。只要没有出现任何问题,系统就可以正常运行,但如果出现故障(网络中断、Kubernetes 代理故障、LDAP 关闭等),则几乎不可能自动做出适当的响应。
虽然尽可能少地接触源系统是一个令人钦佩的目标,但从实际角度来看,在生产系统上独立于源系统运行 CDC 系统几乎是不可能的。如果系统管理员从备份中重新加载旧版本的表或从根本上更改该表的 DDL,CDC 系统必须意识到这种情况已发生并采取适当的操作。在更改 DDL 的情况下,会创建新版本的表,因此必须依次创建新版本的 KTable。
当我们尝试使用上述方法对实际生产系统使用 CDC 时,我们看到了这些问题以及更多问题。我们的结论是,CDC 系统和源系统的管理无法独立完成,并且在很大程度上,我们的问题来自于尝试将 IIDR 用于不适合的用例。
实现 Debezium Db2 连接器的方法
当 Debezium 可用时,我们开始对其进行评估以达到我们的目的。由于它适用于各种关系数据库系统并且是开源的,我们可以想象数据库管理员将允许它用于为下游应用程序生成数据的表示。本质上,Debezium 系统将成为数据库源系统的扩展。Debezium 不需要生成数据库表的相同副本(与 IIDR 或 SQL 复制不同)。通常,下游应用程序用于辅助任务,即分析,而不是用于故障转移,这意味着诸如保留精确类型之类的问题不太紧迫。例如,如果时间戳字段在 Elasticsearch 中表示为字符串,那么这并不是世界末日。
我们对 Debezium 唯一担心的是它没有 Db2 的连接器。
出现了两种方法:
使用低级 Db2 API 像 IIDR 一样直接读取事务日志。
使用 SQL 复制 CDC 捕获表通过 SQL 读取捕获表。
对代码的调查得出的结论是,现有的 Microsoft SQL Server连接器所使用的模型可以在很大程度上被 Db2 重用。在本质上:
轮询更改的 SQL 查询不同
逻辑序列号(LSN)的结构和性质不同
Db2 区分数据库系统和数据库,而 SQL Server 则不需要考虑这一事实。
否则,其他所有东西都可以重复使用。因此,我们调整了现有的 SQL Server 代码库来实现 Db2 连接器。
未来的工作/扩展
标杆管理
Db2 和 SQL Server 连接器使用轮询模型,即连接器定期查询 CDC 表以确定自上次轮询以来发生了什么更改。一个自然的问题是,考虑到轮询本身有成本这一事实,“最佳”轮询频率是多少,即延迟和负载之间的权衡是什么?
我们有兴趣构建一个用于基准测试系统的通用框架,以便更好地了解在延迟、CDC 系统的吞吐量和源系统负载方面的权衡。
Db2 通知系统
除了为 Db2 构建轮询连接器之外,还可以创建一个通知系统。我们考虑了这一点,但认为轮询连接器对于第一次实现来说更简单。
为 Db2 构建通知连接器的一种方法是:
通过使用操作系统文件系统观察程序(Linux 或 Windows)来识别更改事件。这可以监视 Db2 数据库的事务日志目录,并在修改或创建文件时发送事件。
通过使用db2ReadLog API读取实际的表更改来确定事件的确切性质。原则上,该 API 可以作为服务远程调用。
通过SQL连接确定相关的Db2数据结构,例如表DDL。
Debezium 事件驱动的 Db2 连接器将等待通知,然后通过 db2ReadLog 和 SQL 读取实际更改。这需要观察者代理在数据库系统上本地运行,类似于捕获服务器。
DML 与 DDL 的变化
更改数据捕获 (CDC) 系统传播通过数据操作语言 (DML) 操作(例如 INSERT、DELETE 等)对源表所做的修改。它们不会显式处理通过数据定义语言 (DDL) 操作(例如TRUNCATE、ALTER 等。当 DDL 更改发生时,Debezium 应该采取什么行为并不清楚。我们正在探索针对此类变化的 Debezium 模型应该是什么样的。
结论
虽然假设新的企业数据系统完全从头开始构建很有吸引力,但几乎肯定需要在相当长的时间内与现有的关系数据库系统进行交互。Debezium 是一个很有前途的框架,用于将现有企业数据系统连接到 Datalakes 等数据处理平台。我们目前在 IBM Research 的工作重点是构建以 Kafka 和 Debezium 作为核心组件的混合云数据编排系统。