原文地址: https://debezium.io/blog/2018/07/19/advantages-of-log-based-change-data-capture/
欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯.
基于日志的变更数据捕获的五个优点
七月 19, 2018 作者: Gunnar Morling
讨论
昨天,我有机会向达姆施塔特 Java 用户组介绍 Debezium 和变更数据捕获 (CDC) 的想法。这是一个美好的夜晚,有很多有趣的讨论和问题。问题之一如下:与简单地轮询更新记录相比,使用 Debezium 等基于日志的变更数据捕获工具有什么优势?
首先,这两种方法有什么区别?使用基于轮询(或基于查询)的 CDC,您可以重复运行查询(例如通过 JDBC),以从要捕获的表中检索任何新插入或更新的行。相比之下,基于日志的 CDC 通过对数据库日志文件(例如 MySQL 的 binlog 或 MongoDB 的 op log)的任何更改做出反应来工作。
由于这不是第一次出现这个问题,我想我也可以在博客上提供更广泛的答案。这样,如果问题再次出现,我将来就可以参考这篇文章:)
因此,言归正传,以下是我列出的基于日志的 CDC 相对于基于轮询的方法的五个优点。
捕获所有数据更改
通过读取数据库的日志,您可以按照应用程序的确切顺序获得所有数据更改的完整列表。这对于您对记录更改的完整历史记录感兴趣的许多用例至关重要。相反,使用基于轮询的方法,您可能会错过两次轮询循环运行之间发生的中间数据更改。例如,可能会发生在两次轮询之间插入和删除一条记录的情况,在这种情况下,基于轮询的 CDC 永远不会捕获该记录。
与此相关的是停机时间,例如更新 CDC 工具时。使用基于轮询的 CDC,一旦 CDC 工具重新上线,只会捕获给定记录的最新状态,从而错过停机期间对记录发生的任何早期更改。基于日志的 CDC 工具将能够从数据库关闭之前停止的位置恢复读取数据库日志,从而捕获数据更改的完整历史记录。
事件延迟低,同时避免 CPU 负载增加
通过轮询,您可能会想增加轮询尝试的频率,以减少错过中间更新的机会。虽然这在某种程度上有效,但过于频繁的轮询可能会导致性能问题(因为用于轮询的查询会导致源数据库负载)。另一方面,扩大轮询间隔将减少 CPU 负载,但可能不仅会导致错过更改事件,还会导致传播数据更改的延迟更长。基于日志的 CDC 允许您近乎实时地对数据更改做出反应,而无需花费 CPU 时间重复运行轮询查询。
对数据模型没有影响
轮询需要一些指示器来识别自上次轮询以来已更改的记录。因此,所有捕获的表都需要有一些列LAST_UPDATE_TIMESTAMP,可以用来查找更改的行。在某些情况下这可能没问题,但在其他情况下这样的要求可能并不理想。具体来说,您需要确保在所有要由写入应用程序或通过触发器捕获的表上正确维护更新时间戳。
可以捕获删除
当然,轮询不会让您识别自上次轮询以来已删除的任何记录。通常,这对于类似复制的用例来说是一个问题,在这些用例中,您希望源数据库和复制目标上有相同的数据集,这意味着您还希望删除接收器端的记录(如果它们已在源数据库。
可以捕获旧记录状态和更多元数据
根据源数据库的功能,基于日志的 CDC 可以为更新和删除事件提供旧记录状态。而通过轮询,您只能获得当前的行状态。对于许多用例来说,在单个更改事件中方便地使用旧行状态可能很有趣,例如,如果您想向应用程序用户显示包含新旧列值的完整数据更改以进行审计。
此外,基于日志的方法通常可以提供模式更改流(例如,以应用的 DDL 语句的形式)并公开其他元数据,例如事务 ID 或应用特定更改的用户。这些事情通常也可以通过基于查询的方法来实现(取决于数据库的功能),但我还没有真正看到它在实践中完成。
概括
就是这样,基于日志的变更数据捕获的五个优点。请注意,这并不是说基于轮询的 CDC 没有其应用程序。例如,如果您的用例可以通过每小时传播一次更改来满足,并且错过之间有效的记录的中间版本也不是问题,那么就完全没问题。
但是,如果您有兴趣近乎实时地捕获数据更改,确保您不会错过任何更改事件(包括删除),那么我非常建议您探索基于日志的 CDC 的可能性,如德贝西姆。Debezium 连接器为您完成所有繁重的工作,即您不必处理各个数据库的所有低级细节以及从日志中获取更改的方法。相反,您可以使用 Debezium 生成的通用且基本统一的变更数据事件。