【51CTO.com快译】数据是数据平台最重要的资源,企业需要对如何将数据摄取到新的数据平台中进行设计和规划。
本文将讨论变更数据捕获(CDC)解决方案,如何基于Debezium等开源工具设计标准的复制解决方案,以及CDC可以帮助企业迁移到新的数据平台的原因。
什么是变更数据捕获(CDC)
变更数据捕获(CDC)是一个软件过程,它捕获在源数据库中所做的变更(DDL和DML)以同步另一个数据存储库,例如数据库、内存缓存、数据仓库或数据湖。CDC用于本文没有讨论的其他互补的用例,例如:
- CQRS模式:其中一种实现涉及具有单独的写入(命令)和读取(查询)数据库和数据模型。写入层支持插入、更新和删除操作,读取层支持查询数据操作。CDC允许将命令操作从写入数据库复制到读取数据库。
- 分析微服务:提供变更事件流以跟踪变更发生的时间和内容,并分析行为模式。
CDC解决方案由三个主要组件组成:
- 源连接器:它从数据库中捕获变更并生成包含这些变更详细信息的事件。
- 通道:它是源连接器将这些事件与变更保持在一起的数据存储库。
- 接收器连接器:从通道读取事件并处理应用特定逻辑以将数据整合到目标系统或其他目的(例如分析警报过程)。
实现CDC有多种方法,例如基于日志、基于触发器或基于SQL脚本。本文将关注基于日志的方法,因为它是一种更有效的方法,以下将描述这种方法的优点。
源连接器发布的事件包含同步远程数据存储库所需的所有信息。它由以下部分组成:
- 元数据:提供诸如表名、操作类型(插入、删除等)、事务标识符、源连接器进行或捕获变更时的时间戳等信息。
- 前值:变更前的数据值。
- 后值:变更后的数据值。
- JSON
- {
- "table":"stock"
- "operation": "update",
- "ts_ms" : "1627817475",
- "transaction_id": 2,
- "before" : {
- "id" : "0001",
- "item" : "T-Shirt",
- "quantity" : "10"
- },
- "after" : {
- "id" : "0001",
- "item" : "T-Shirt",
- "quantity" : "5"
- }
- }
并非所有连接器都具有相同的行为。有一些连接器(例如官方的MongoDB连接器)不提供“前值”。
在数据复制的情况下,这些事件由接收器连接器使用,并合并到目标数据库中。企业必须按照事件生成的顺序使用事件,以确保流程的弹性。
如果事件没有按顺序进行,就不能保证复制过程的弹性。以下是可能发生的一些场景的示例:
在复制以外的场景中,基于事件驱动模式以及想要对特定事件做出反应的情况下,按顺序使用事件并不重要。
基于日志的CDC优势
与其他CDC方法或ETL复制过程相比,基于日志的CDC具有以下一些优势:
- 性能:通过读取该文件,从事务日志文件中检索所有变更。与ETL等其他方法相比,这种操作对数据库性能的影响较小。ETL方法是基于SQL查询,需要持续优化(索引、分区等),因此将消耗大量计算资源。
- 解耦数据提取:它提供解耦数据提取计算层,与其余工作负载隔离。这个解决方案允许仅在CDC解决方案上进行垂直和水平扩展。触发器CDC方法使用数据库计算层,此复制过程可能影响数据库的性能。
- 接近实时:低计算影响能够提供接近实时的事件变更,而不会对源数据库造成风险。检测有序文件中的变更比对表进行查询轮询过程更容易、更快。
- 捕获所有变更:事务日志按确切顺序提供所有数据变更,其中包括删除操作。ETL过程忽略了ETL执行之间发生的中间数据变更。可以使用其他方法(ETL、基于CDC触发器、CDC SQL)识别删除操作需要创建表来注册此操作,以及确保数据弹性的特定逻辑。
- 不影响数据模型和应用程序:这不需要变更数据模型或源应用程序。ETL和其他CDC解决方案需要创建触发器和表或向表中添加时间戳。
需要考虑一些重要的细节:
- 无日志事务操作:所有操作都不会在事务日志上注册。数据仓库中通常使用目录级别的操作,例如目标表和临时表之间的分区移动。这种类型的操作取决于每个数据库版本以及团队的工作方式。
- 商业工具:每个数据库供应商都提供特定于CDC的工具,通常带有附加许可证。在复杂的多供应商环境中,企业使用不同的CDC工具来复制数据会增加运营成本。
- 开源工具:它们是一个不错的选择。通常需要更多时间来更新数据库供应商发布的新功能。有时,对故障排除或错误解决的支持更为复杂。
- 反模式:在某些情况下,必须将特定源数据库复制到多个目标数据库。有时,团队会配置多个CDC复制,所有这些复制都从同一个事务日志中读取。这是一个危险的反模式。低影响并不意味着没有影响,CDC会增加I/O操作,因此从同一文件中读取多个CDC会增加大量I/O操作,并产生I/O的性能问题。而使用中心辐射模式是一种更好的方法。
中心辐射型CDC模式(Data Hub)
中心辐射式架构是最常见的数据集成架构模式之一。这种架构允许一次从数据库中捕获变更并多次交付它们。这种模式与Apache Kafka和其他流媒体平台使用的发布和订阅模式非常相似,并具备一些好处,例如:
(1)可重用性:更改事件从源数据库读取一次,并由接收器连接器多次使用。
(2)减少集成次数:与源数据库只有一次集成。
(3)标准接口:为所有消费者提供相同的接口。在这种情况下,接收器连接器复制共享同一接口的目标数据库中的数据。
根据通道的特性,它将允许提供一些Data Hub的功能。数据保留是Data Hub的一项基本功能。如果无法存储所有历史数据甚至每个文档或行的最后状态,用户将不得不采用其他工具和流程来补充解决方案。
CDC的常见场景
CDC是一个很好的解决方案,并且有四种常见的场景:
- OLAP数据库迁移:在企业将所有或部分工作负载从当前数据仓库迁移到新的OLAP解决方案的情况下,CDC允许将相同的数据复制到另一个系统并使迁移变得更容易。如今,许多企业正在将工作负载从内部部署数据库迁移到数据云解决方案。
- 将信息从OLTP数据库复制到OLAP数据库:将数据从运营数据库复制到数据仓库或数据湖。
- 数据库即服务:为分析沙箱或提供数据库的副本。
- 从单体到微服务的迁移:应用扼杀者模式将单体应用程序逐步迁移到微服务。在第一阶段复制两个应用程序共存所需的一些数据集。
企业CDC解决方案
下图描述了CDC进程的行为方式以及组成它的组件。基于此提出以下解决方案架构:
- Debezium作为源连接器:这一部分将负责从源数据库引擎读取变更并将其发送到通道。它将作为连接器部署在Kafka Connect集群中。
- Kafka作为通道:它提供中间存储以及用于事件生产/消费的广泛API和可部署在Kafka Connect或其他平台上的大型生态系统连接器。
- Kafka Sink JDBC(Confluent提供)与Event flattering SMT(Debezium提供)作为Sink连接器:这个连接器允许用户使用一些配置参数在目标数据库上执行复制。作为一个通用解决方案,这是一个不错的选择。在其他情况下,例如Snowflake或其他云服务,JDBC连接器的成本效益和性能比供应商本身提供的其他策略更差。评估切换到供应商本身提供的连接器而不是使用通用JDBC的成本收益是很重要的。
- Kafka Connect as Connector Platform:它提供了一个框架,可以基于简单的配置将连接器部署为插件,并与Kafka完全集成。这是一个非常好的选择,因为它允许企业标准化接收器/源连接器管理,例如Debezium复制操作和JDBC接收器连接器。
1.Debezium
Debezium是一个开源解决方案,提供了非常有趣的功能来捕获数据库中的变化。Debezium架构提供了一些优势,例如:
与特定的数据库供应商解决方案相比,事件标准化是使用Debezium等产品的重要优势之一。通常情况下,每个供应商解决方案都有不同的事件规范,因为这些解决方案主要设计用于复制来自同一供应商的数据库。在多个数据库产品之间进行复制处理的场景中,具有多个事件规范会增加解决方案在操作、可维护性和编码方面的复杂性。Debezium提供了一个通用、清晰且简单的事件规范,可以促进与其他第三方产品(例如Kafka Connect接收器连接器)的集成。
以下看一个事件示例(为了便于阅读而进行了调整):
- JSON
- {
- "after": {
- "field_id": 1,
- "field_1": "Value 1"
- },
- "before": null,
- "op": "c",
- "source": {
- "connector": "mysql",
- "db": "inventory",
- "name": "mysqldb",
- "snapshot": "false",
- "table": "product",
- "ts_ms": 1627489969029,
- "version": "1.6.1.Final",
- (... other source vendor fields ...)
- },
- "transaction": null,
- "ts_ms": 1627489969200
- }
- after:包含表格列及其值的文档。其值可以为null,例如在删除操作中。
- before:包含表格列及其值的文档。其值可以为null,例如在创建(插入)操作中。
- op:在数据库中运行的操作,如更新、插入或删除。
- source:事件的元数据。该文档具有公共信息,但它有几个字段,具体取决于源数据库(Oracle、SqlServer、MySQL或PostgreSQL)。
- t source.ts_ms:表示在数据库中进行更改的时间。
- ts_ms:Debezium处理该事件时的时间戳,与source.ts_ms不同。通过比较这些值,可以确定源数据库更新和Debezium之间的延迟。
Debezium与Kafka生态系统完全集成。源连接器使用Kafka API发布更改事件,但也可以部署为Kafka连接器。可以使用REST API将其部署在Kafka Connet集群中,以简化新CDC源连接器的部署和管理。
- JSON
- {
- "name": "debezium-postgres-inventory-connector",
- "config": {
- "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
- "tasks.max": "1",
- "database.hostname": "postgres",
- "database.port": "5432",
- "database.user": "postgres",
- "database.password": "postgres",
- "database.dbname": "postgres",
- "database.server.name": "postgresdb",
- "schema.include": "inventory",
- "table.include.list": "inventory.product"
- }
- }
在这个示例中,在PostgreSQL数据库中部署了一个新的Debezium源连接器,并启用了对库存模式上产品表的变更捕获。连接器读取更改并将事件推送到Kafka主题“postgres.inventory.product”。
尽管每个Debezium数据库连接器都有特定的配置、属性和选项,但也有通用的连接属性。作为一个常见的选择,可以在第一次配置数据库快照到Kafka或禁用它。这些通用配置属性加入Kafka连接器API,提供了一个标准的管理源连接器层,可以简化解决方案的操作。
需要考虑的事项:
虽然有多种Debezium连接器,但并非所有连接器都提供相同的功能:
- MongoDB
- MySQL
- PostgreSQL
- Oracle
- Etc
在做出决定之前,对每一项进行审查非常重要,因为在某些情况下,使用供应商连接器可能会更好,例如:
- Debezium MongoDB Source Connector:目前无法发送文档的当前状态,只能发送幂等格式的操作。
- Debezium SQL Server Source Connector:它不是基于日志的连接器,而是基于触发器的连接器,它需要安装触发器过程并创建一个阶段表。
2.Kafka
Kafka是提供通道功能的一个很好的选择,因为它提供了几个重要的功能,例如:
- 可扩展的事件流平台:高度可配置以提供高可用性、低延迟、高性能、多次交付和持久性保证。
- 发布/订阅模式:它促进了一次发布和多次消费的机制,提供了良好的系统,每个用户可以或按照希望提供的速度工作。
- 大型生态系统:如今已被数千家公司使用。有许多用于数据管道、流分析和数据集成的开源和商业工具。
- 无限存储和保留:提供具有无限存储和保留的集中平台。Confluent最近提供的一些功能让用户能够拥有更好的成本效益存储层,将存储和计算资源解耦。
Debezium CDC事件发布在Kafka主题中。一个Kafka事件由三部分组成:
- 键:用于确定将附加消息的分区。具有相同事件键的事件被写入同一个分区。Kafka保证分区的事件将被任何消费者以与写入它们完全相同的顺序读取。
- 值:它包含事件本身。
- 标头:它是与Kafka记录关联的元数据,并提供有关键/值对的额外信息。
作为一个键,Debezium包含了表的键域。这允许用户按照变更事件在数据库中发生的顺序处理变更事件。
(1)主题策略
活动发布有两种策略:
- 每个表有一个主题。
- 每个数据库有一个主题或一对数据库和模式有一个主题。
最佳策略取决于环境的特征,两种解决方案各有利弊。“每个表有一个主题”策略的主要问题是所需的主题和分区的数量。Kafka对每个集群有一个分区限制,所以当用户的很多数据库有成百上千的表时,不建议使用这种策略。
(2)表现
这个解决方案中有两个级别的并行性:
- 基于目标数据库的数量。
- 特定目标数据库的吞吐量。
Kafka提供了发布/订阅模式,这允许用户部署多个接收器连接器来处理事件,并将信息从主题并行复制到多个目标数据库。为了增加每个接收器连接器的吞吐量,需要组合两个组件:
- 主题分区的数量。
- Kafka消费者组中的消费者数量。每个接收器连接器都与一个特定且独特的消费者群体相关联。在Kafka连接器的情况下,消费者统一体就像一个线程或任务。
资源组的成员划分分区,以便分区仅由组的消费者使用,并且该消费者将按顺序读取键的事件。基于此,可以使用Kafka Connect来处理影响每个键的事件以将状态复制到另一个目标数据库中,例如一个简单配置的数据仓库,例如:
- JSON
- {
- "name": "jdbc-sink",
- "config": {
- "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
- "tasks.max": "1",
- "topics": "postgres.inventory.product",
- "connection.url": "jdbc:dwhdriver://connection",
- "transforms": "unwrap",
- "transforms.unwrap.type": "io.debezium.transforms.ExtractNewRecordState",
- "transforms.unwrap.drop.tombstones": "false",
- "auto.create": "true",
- "insert.mode": "upsert",
- "delete.enabled": "true",
- "pk.fields": "id",
- "pk.mode": "record_key"
- }
- }
一个连接器可以读取多个主题,并且可以在作为用户组工作的任务中进行扩展。使用此配置中定义的属性,可以执行源的副本,或者可能仅将事件作为历史演变附加以执行某些分析过程。
(3)数据保留
Kafka数据保留在主题级别进行管理,并且有不同的策略:
- 时间保留:超过时间时,Kafka代理会定期删除旧事件。
- 大小保留:当超过主题大小时,Kafka代理会定期删除旧事件。
- 无限制。
作为一个有趣的新功能,Confluent提供了分层存储:可以将热数据发送到经济高效的对象存储,并且仅在需要更多计算资源时进行扩展。在某些情况下,数据可能需要无限长的存储时间。
按时间或大小保留并不是Kafka定义清理策略的唯一能力。用户可以定义一个紧凑策略,其中Kafka代理定期删除事件,只保留每个键的最后一个事件,并在最后一个事件为null作为s值时删除该键。
压缩策略是CDC解决方案的一个非常有趣的功能。它允许用户保留行或文档的最后一个事件。这意味着用户拥有最后的合并值,但丢失了变更的历史记录。
压缩清理策略是一项代价昂贵的操作,但它允许用户清理旧事件,保持数据库的最后状态,其优点是,如果一年后需要新的使用者,则不需要处理这一年发生的事件。
结论
在有大量数据和技术多样的复杂环境中,为新的数据平台提供数据是一个巨大的挑战。但真正的挑战是在提供这些数据的同时确保企业做出有价值决策所需的质量。
准确性、一致性、唯一性、及时性是衡量数据质量的一些指标。CDC代替了其他解决方案,使用户能够以相对简单的方式标准化数据摄取并确保数据质量。而标准化和自动化是提高任何流程质量的关键。
原文标题:Data Platform: Building an Enterprise CDC Solution,作者:Miguel Garcia,Dario Cazas Pernas
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】