在这篇博文中,我们将讨论如何做到这一点Delhivery印度领先的供应链服务公司,正在使用Debezium来支持许多不同的业务用例,从驱动事件驱动的微服务,提供数据集成和移动运营数据开云体育官方注册网址到数据仓库进行实时分析和报告。我们还将讨论我们在集成Debezium时所犯的早期错误,以及我们如何解决这些错误以便将来的用户可以避免这些错误,讨论我们面临的一个更具挑战性的生开云体育官方注册网址产事件,以及Debezium如何帮助我们确保在没有任何数据丢失的情况下恢复。最后,我们讨论了Debezium为我们提供了什么价值,我们认为还有改开云体育官方注册网址进空间的领域,以及Debezium如何适应我们未来的目标。

开云体育官方注册网址Debezium交付

我们在物流领域工作,因此我们编写的大部分软件都围绕着状态——货物的状态变化、跟踪位置更新、收集实时数据并对其做出反应。在任何软件体系结构中,您可能会发现“状态”最常见的地方是数据库。开云体育电动老虎机我们主要在文档数据库(如MongoDB)和关系数据库系统(特别是PostgreSQL)中维护我们所有的事务数据,用于组织内的不同服务开云体育电动老虎机。有必要对所有不同数据源的交易数据进行高效和近乎实时的分析,以实现表面见解,并查看组织如何运作的大局,并做出数据驱动的决策。

为了解决上述目标,我们使用Debezium对我们的事务数据执行变更数据捕获,开云体育官方注册网址使其在Kafka中可用,Kafka是我们选择的消息代理。一旦数据在Kafka中可用,我们可以做以下一项或所有工作:

  • 在不同关系表的更改流之间执行流连接或数据丰富(甚至可能来自不同的数据库或服务)。开云体育电动老虎机如。利用行程和车辆数据丰富货运)

  • 从变更流创建域事件以供下游服务使用(例如。从三个不同的变更流中创建包含订单、装运和产品信息的聚合消息)

  • 将变更流数据移动到数据湖中,以支持灾难恢复或重放部分数据

  • 复杂的事件处理,以生成实时指标和电源仪表板(例如;运输物品的实时计数,每个区域内的平均行程时间等)

开云体育官方注册网址Debezium通过提供一个通用的平台和框架来连接我们现有的数据源(如MongoDB、PostgreSQL或MySQL),使上述所有用例都成为可能,并且非常容易构建。

本文将分享我们在AWS RDS (AWS的托管数据库服务)上使用Debezium的经验,希望能帮助我们转移在这个开云体育官方注册网址过程中获得的一些知识,并记录如何从PostgreS开云体育电动老虎机QL的WAL中跳过不可解析的记录dbz - 1760是固定的(已经实现,计划在下一个Debezium 1.1预览版发布)。开云体育官方注册网址

下面是一个简短的架构概述,展示了Debezium支持的一些用例和通用数据平台。开云体育官方注册网址

图1。当前的体系结构

但要达到上述目标是一个反复的过程,需要进行大量的实验和试验。

开云体育官方注册网址Debezium与PostgreSQL在AWS RDS

现在我们将讨论在AWS RDS上使用PostgreSQL运行Debezium的一些经验教训。开云体育官方注册网址我们不打算关注如何在RDS上使用Debezium和PostgreSQL,因为它在开云体育官方注册网址PostgreSQL连接器的文档

经验教训

我们首先创建了一个概念验证,其目标是侦听单个PostgreSQL数据库中3个不同表的更改,并在下游创建两个视图,一个作为三个表的连接,另一个视图包含作为时间序列跟踪的聚合指标。开云体育电动老虎机连接和聚合都是使用卡夫卡流因为与其他流处理框架相比,它更容易设置和学习。因为Debe开云体育官方注册网址zium已经提供了非常丰富的特性Docker容器镜像我们稍微扩展了一下,决定在AWS的弹性容器服务(Elastic Container service)上以容器的形式运行该服务,这是一种容器编排服务。

我们刚开始的时候犯了一些错误。对于我们的错误,所有的解决方案现在都记录在Debezium文档中,但是为了避免这些错误,这里将它们都列在一起。开云体育官方注册网址

  • 我们最初使用wal2json插件导致连接器遇到OutOfMemoryError当提交大型事务(其序列化形式使用的内存超过可用Java Heap空间的事务)时。因此我们的建议是:

    • 在PostgreSQL < 10时,使用wal2json_streaming避免插件OutOfMemoryError大型交易。

    • 在PostgreSQL >= 10上,使用pgoutput插件。

  • 我们使用模式生成JSON消息;这会创建比需要的更大的Kafka记录,特别是当模式更改很少时。因此,我们决定通过设置禁用消息模式key.converter.schemas.enabled而且value.converter.schemas.enabled大大减少每个有效负载的大小,从而节省网络带宽和序列化/反序列化成本。唯一的缺点是我们现在需要在外部模式注册表中维护这些消息的模式。

  • 我们观察了一些使用base64编码数据的数据类型。作为记录,这是NUMERIC列的默认值,但对于使用者来说可能很难处理。为了转换为一种更容易解析的格式,以牺牲一些准确性为代价,我们配置了特定于数据类型的属性作为记录.具体来说,集合decimal.handling.mode字符串接收NUMERIC, DECIMAL和等效类型作为字符串(例如。“3.14”)并设置hstore.handling.modejson以JSON字符串形式接收HSTORE列。

  • 始终确保基本的卫生检查,如数据库磁盘使用情况、事务日志磁盘使用情况以及用于读写操开云体育电动老虎机作的网络和磁盘带宽。没有在事务日志和数据库上的磁盘使用情况上设置警报。开云体育电动老虎机我们在RDS指标上添加了警报TransactionLogsDiskUsage而且OldestReplicationSlotLag当事务日志磁盘使用率增加到阈值以上或当复制插槽开始滞后时提醒我们—这意味着Debezium可能已经死亡。开云体育官方注册网址

  • 我们没有在Debezium中启用心跳。开云体育官方注册网址心跳是需要控制的WAL磁盘空间消耗以下情况:

    • 被监控的数据库中有很多更新,但只有很少一部分与被监控的表和/或模式相关。开云体育电动老虎机我们通过设置启用心跳来处理这种情况heartbeat.interval.ms

    • PostgreSQL实例包含多个数据库,其中被监控的数据库与其他数据库相比流量较小。开云体育电动老虎机由于WAL由一个实例中的所有数据库共享,它会不断积累数据,直到开云体育电动老虎机Debezium读取这些数据时才能删除这些数据。开云体育官方注册网址但是由于不监控高流量数据库,Debezium无法与数据开云体育电动老虎机库通信,因此可以删除WAL文件以回收磁盘空间。开云体育官方注册网址为了解决这种情况,我们通过定期更新被监控数据库中创建的表中的单行来触发“heartbeat”事件,使用以下查询:开云体育电动老虎机

      创建表格如果存在心跳(id SERIAL)主要的关键, ts时间戳时间区);插入心跳(id, ts)1现在())冲突(id)更新ts = EXCLUDED.ts;

      由于这是与PostgreSQL一起使用Debezium时出现的常见用例,因此在跟踪此问题时产生了一个问题开云体育官方注册网址dbz - 1815

  • 我们严重降低了带有JSONB列的表的吞吐量。经过调试,我们确认了Debezium频繁刷新模式的原因,因为在复制消息中没有出现TOASTed列。开云体育官方注册网址这是通过改变来解决的schema.refresh.modecolumns_diff_exclude_unchanged_toast从那以后记录

  • 我们在一些RDS实例大小的数据库连接上观察到频繁的EOF错误。开云体育电动老虎机我们仍然不确定原因,但初步调查指出,问题只发生在附加了PgBouncer的实例(即使没有通过PgBouncer连接)或较小大小的实例(AWS t2/t3系列)上。

  • 我们最初为每个PostgreSQL数据库使用一个Deb开云体育官方注册网址ezium连接器(而不是每个主机),但后来改为为开云体育电动老虎机每个团队使用一个连接器。不为每个PostgreSQL实例运行单个连接器的主要原因是工作负载隔离。任何执行大量数据更新、删除或计划外模式迁移的团队只会影响他们自己的Debezium连接器,而不会影响整个PostgreSQL实例,因为Debezium会根据配置的数据库和/或模式白名单和黑名单过滤事件。开云体育官方注册网址开云体育电动老虎机我们正在尝试识别此配置中可能存在的问题,但尚未发现任何问题。移动到每个团队设置的单个连接器也减轻了许多关于配置更改的管理开销,因为在为任何更改创建发布计划时,我们不再需要在多个团队之间协调。尽管单个数据库上的多个复制插槽确实会增加开销,但我们能够在每个数据库主机上运行6到10个复制插槽开云体育电动老虎机,而不会有明显的性能影响。

生产事故

与每个软件开发项目一样,我们确实遇到了一些问题,在这里我们详细讨论一个比较困难的问题。但由于Debezium专注于开云体育官方注册网址确保数据一致性,我们能够恢复没有任何数据丢失。

我们下面讨论的问题在Debezium 1.0中已经修复,您应该尽快更新开云体育官方注册网址

一般来说,跳过此类不可处理事件的新特性被合并为公关# 1271在Debezium核心框开云体育官方注册网址架中,并将成为下一个Debezium 1.1预览版的一部分。

开发人员经常做不到的两件事是适当的日期时间处理和软件版本升级。这两种情况都可能导致各自的问题,但当两者同时发生时,会使事情变得困难。我们最近遇到了这样的问题,并提供了一种处理方法。我们先来了解一下为什么会出现这个问题。

PostgreSQL的日期/时间类型文档TIMESTAMP类型的范围为公元前4713年公元294276年.在Debezi开云体育官方注册网址um 0.10之前,有几个关于日后日期溢出的问题,比如dbz - 1255而且dbz - 1205

Bug和如何处理

要解决上述问题,你需要有一个足够遥远的未来日期。如果您没有使用ISO8601或epoch时间,并且自定义日期时间格式化程序中有错误,则可以获得一个。

因此,该错误是由应用程序写入包含年份的datetime值触发的20200这导致Debezium抛出一个异常,因为我们仍然在生产环境中运行0.9。开云体育官方注册网址

不幸的是,我们的日志模式警报那天没有工作,错误会悄悄地跳过我们,直到高复制延迟警报触发。在检查日志之后,我们确定了问题的来源和价值。不幸的是,日志没有告诉问题在哪个表中(提示-可以成为一个有价值的贡献),以及哪一列包含有问题的值。幸运的是,只监视了四个表,每个表都有两个TIMESTAMPTZ列,很容易查询其中的错误值以找到实际的记录。

快速阅读源代码表明,任何年份> 9999都会发生这种情况,因此我们查询数据库以检查是否存在其他类似的值。开云体育电动老虎机谢天谢地,没有其他价值存在。到目前为止,我们已经有了一个明确的计划:

  1. 停止Deb开云体育官方注册网址ezium

  2. 更正数据以作记录

  3. 想办法让Debezium开云体育官方注册网址跳过不可解析的记录

  4. 向数据库添加验证,以确保这些值暂时不会开云体育电动老虎机跳过

  5. 将Debeziu开云体育官方注册网址m升级到1.0

但是我们在上面的第三步被卡住了,因为我们找不到与MySQL相同的选项event.deserialization.failure.handling.mode用于PostgreSQL连接器。

Debe开云体育官方注册网址zium和PostgreSQL如何跟踪补偿

PostgreSQL中的每个变更记录都有一个位置,该位置使用一个称为日志序列号(LSN)的值来跟踪。PostgreSQL将其表示为两个十六进制数-逻辑xLog而且.开云体育官方注册网址Debezium将其表示为该值的十进制表示。实际的转换实现可以在PostgreSQL的JDBC驱动程序中看到在这里

Debezium周期性地将开云体育官方注册网址最后处理的LSN和事务id写入Kafka Connect偏移主题,并将复制槽向前推进以匹配。在启动时,Debeziu开云体育官方注册网址m使用来自Kafka Connect偏移主题的最后一条记录,将复制插槽倒回到继续流更改之前所描述的位置。这意味着要改变Debezium在WAL中的位置,需要同时改变Kafka Connect offset topic开云体育官方注册网址中Debezium的跟踪信息,以及PostgreSQL中的服务器端。

跳过不可解析事件

通过执行以下步骤,我们能够使用上述信息使Debezium跳过不可解析事件:开云体育官方注册网址

  1. 停止Deb开云体育官方注册网址ezium使复制槽处于非活动状态。

  2. 通过运行检查开云体育官方注册网址Debezium已停止在复制插槽上监听SELECT * FROM pg_replication_slots WHERE slot_name = '';.的活跃的列应为f

  3. 检查Debezium偏移主题中的最后一条消息,并记下开云体育官方注册网址lsn关键。如。1516427642656

  4. 使用以下Java代码,使用PosgtreSQL的Java驱动程序将LSN的长表示转换为十六进制格式:

    进口org.postgresql.replication.LogSequenceNumber刮伤公共静态无效主要(字符串[]参数){LogSequenceNumber a = LogSequenceNumber. valueof (1516427642656 l);系统.out.println (a.asString ());}}
  5. 从WAL往上看变化到上面使用的LSNSELECT pg_logical_slot_peek_changes('', '', 1).这是我们将要跳过的复制更改,因此请确保这是您想要跳过的记录。确认后,进行下一步。

  6. 通过跳过使用的1个更改来推进复制插槽SELECT pg_logical_slot_get_changes('', NULL, 1).这将消耗来自复制插槽的1个更改。

  7. 用下一个LSN和TxId发布消息到Debe开云体育官方注册网址zium的偏移主题。我们可以成功地让它工作通过给两个lsntxId

  8. 再次部署Deb开云体育官方注册网址ezium,它应该跳过记录。

结论

为什么D开云体育官方注册网址ebezium ?

最后,我们想强调Debezium为我们解决的问题。开云体育官方注册网址

在处理任何数据时,最大的问题之一是关于数据一致性,Debezium帮助我们避免双重写入,并维护RDBMS和Kafka之间的数据一致性,这使得更容易确保所有层的数据一致性。开云体育官方注册网址

开云体育官方注册网址Debezium支持低开销的变更数据捕获,现在我们已经默认为所有正在创建的新数据源启用Debezium。

开云体育官方注册网址Debezium对各种数据源的支持,特别是PostgreSQL, MySQL和MongoDB,帮助我们提供了一个标准的技术和平台来执行数据集成。不再需要编写自定义代码来连接每个数据源。

开云体育官方注册网址Debezium是开源的,在早期被证明是非常有用的,它可以确保我们自己为一些错误发送补丁,而不必让别人优先考虑这个问题。由于它是开源的,所以围绕它的社区在不断壮大,可以帮助您解决问题并提供一般性指导。看看这个页面在Debezi开云体育官方注册网址um网站上有很多很棒的社区贡献的内容。

挑战

上面提到的Debezium仍然是一个相当年轻开云体育官方注册网址的项目,在一些方面还有待改进(你也可以在代码、设计、想法、文档甚至博客文章等方面做出贡献):

  • 零停机时间高可用性。开云体育官方注册网址Debezium依赖于Kafka Connect框架来提供高可用性,但它没有提供类似于热备用实例的东西。现有连接器关闭和新实例出现需要一段时间——这对一些用例来说可能是可以接受的,但对其他用例来说是不可接受的。看到这篇博文由BlaBlaCar撰写讨论和解决方案。

  • 支持Kafka以外的其他数据接收器。在一些场景中,您可能希望直接将事件从数据库移动到API、不同的数据存储或不同的消息代理。开云体育电动老虎机但是由于Debezi开云体育官方注册网址um目前是在Kafka Connect上编写的,所以它只能将数据写入Kafka。开云体育官方注册网址Debezium确实提供了一个嵌入式引擎,您可以将其作为一个库来使用Java应用程序中的更改事件。看到关于嵌入Debezium的文档开云体育官方注册网址.如果您最终要围绕Debezium编写不同的适配器来将数据移动到不同的目的地,请考虑将其开源,这样您就可以从额外的维开云体育官方注册网址护者中受益,社区也可以通过解决新的用例而受益。

  • 编写任何新的CDC实现的通用框架。我们特别有一个在AWS DynamoDB上执行CDC的用例。我们可以重用Debezium核心框架,只编写DynamoDB特定的部分,而不是从头开始编写定制的Kafka连接器。开云体育官方注册网址这将有助于防止错误,因为许多现有的流和边缘情况可能已经被处理了。围绕这个主题正在进行的工作是重构所有现有的Debezium连接器,以使用通用框架,从而更容易编写新的自定义连接器。开云体育官方注册网址有关如何实现的示例,请参阅开云体育官方注册网址Debezium培养库

  • 一些小问题已经在项目的问题跟踪器上被跟踪了DBZ-1760(跳过不可解析的记录)DBZ-1263(现有连接器更新表白名单)DBZ-1723(失败时重新连接到DB)DBZ-823(并行快照)

未来的范围

我们确实计划了一些未来的任务来改进我们现有的关于Debezium和Kafka Connect的工作流程。开云体育官方注册网址

  • 升级到Debezium v开云体育官方注册网址1.0。开云体育官方注册网址Debezium最近发布了第一个1.0版本,其中包含许多新特性,包括支持CloudEvents格式我们希望为整个组织的所有数据提供统一的消息格式。

  • 尝试文档中所述的发件箱设计模式使用发件箱模式进行可靠的微服务数据交换统一应用程序事件和数据更改事件。发件箱模式还在微服务系统中提供跨服务边界的事务保证——这是每个人在基于事件的微服务架构中都想要的。

  • 建立Apache阿特拉斯集成以自动创建数据源和跟踪Atlas中的数据沿袭,以帮助数据治理和可发现性。

  • 编写并开源AWS DynamoDB CDC连接器作为Debezium连接器。开云体育官方注册网址因为我们也在使用AWS DynamoDB,所以我们需要提供其他数据源在CDC方面使用的相同功能。为此,我们正在编写一个使用Debezium作为框架的DynamoDB CDC连接器。开云体育官方注册网址这项工作仍处于早期阶段,计划作为开源连接器发布。

所以总的来说,我们以分享我们的业务用例开始这篇文章,并讨论了Debezium如何帮助我们解决这些用例。开云体育官方注册网址然后,我们详细介绍了如何在生产环境中运行Debezium,在AWS RDS上的Pos开云体育官方注册网址tgreSQL上执行CDC,并讨论了我们在开始时所犯的错误以及如何解决这些错误。正如软件工程中常见的那样,我们确实在开发过程中遇到了一些生产事故,我们正在分享从那次事故中得到的教训,希望它们对更广泛的社区有用。

也非常感谢评论这篇文章的人,包括贡纳MorlingKapil巴拉蒂而且阿卡什深维尔马

Ashhar哈桑

Ashhar是delivery的软件工程师,他专注于变更数据捕获、数据仓库和创建事件驱动系统。


关于Debe开云体育官方注册网址zium

开云体育官方注册网址Debezium是一个开源的分布式平台,它将现有数据库转换为事件流,因此应用程序几乎可以立即看到并响应数据库中提交的每一个行级更改。开云体育电动老虎机开云体育官方注册网址Debezium是建立在卡夫卡并提供卡夫卡连接监控特定数据库管理系统的兼容连接器。开云体育电动老虎机开云体育官方注册网址Debezium在Kafka日志中记录了数据更改的历史,所以你的应用程序可以在任何时候停止和重新启动,并且可以很容易地使用它没有运行时错过的所有事件,确保所有事件都被正确和完整地处理。开云体育官方注册网址Debezium是开源Apache许可证,版本2.0

参与

我们希望您觉得Debezium有趣开云体育官方注册网址且有用,并愿意尝试一下。在Twitter上关注我们@开云体育官方注册网址debezium在Zulip上和我们聊天,或加入我们的邮件列表与社区对话。所有的代码都是开源的GitHub上,因此在本地构建代码并帮助我们改进现有连接器并添加更多连接器。如果您发现了问题或对我们如何改进Debezium有想法,请告诉我们开云体育官方注册网址记录问题

Baidu
map