精确一次投递

概述

Debezium 提供至少一次(at-least-once)的投递保证。这意味着不会丢失任何变更;然而,在某些情况下,记录可能会被投递不止一次。在某些场景下,这些重复的记录可能会产生问题,并且可能需要精确一次(exactly-once)语义。

精确一次投递确保每条变更都被投递,并且在变更流中最多出现一次。这比至少一次投递的要求要严格得多。

目前,Debezium 没有实现内部的去重层来强制执行精确一次语义。然而,当 Debezium 作为源连接器部署在 Kafka Connect 框架中时,它可以利用 Kafka Connect 对精确一次投递的支持。

Kafka Connect 对源连接器提供精确一次支持

Kafka Connect 在 KIP-618 中引入了对源连接器精确一次投递的支持。此功能建立在 Kafka 的事务支持和 KIP-98 中引入的精确一次投递机制之上。

已知问题和注意事项

虽然精确一次投递在 Kafka 和 Kafka Connect 中已经可用一段时间了,但目前尚不清楚其实现是否完全正确,或者是否存在可能违反精确一次语义的边缘情况。

迄今为止,还没有一项全面的研究分析过近期 Kafka 版本中事务和精确一次实现的正确性。然而,两份 Jepsen 报告,一份针对 Redpanda,另一份针对 Bufstream,都指出了 Kafka 协议及其实现的潜在问题。这些报告对正确性提出了担忧,尤其是在 Bufstream 的案例中。

因此,Apache Kafka 中一些相关的开放问题仍然存在:

由于 Kafka Connect 的精确一次投递依赖于 Kafka 事务,因此可以合理地推断,这些问题也可能影响 Kafka Connect 的精确一次保证。

虽然没有深入的研究来分析 Kafka Connect 精确一次投递的正确性,但 Kafka 事务协议中存在已知问题,这些问题也可能影响 Kafka Connect 精确一次投递的正确性。

支持精确一次投递的 Debezium 连接器

以下 Debezium 源连接器支持参与 Kafka Connect 的精确一次投递。

  • MariaDB

  • MongoDB

  • MySQL

  • Oracle

  • PostgreSQL

  • SQL Server

配置

先决条件

Kafka 必须运行在分布式模式下,并且 Kafka Connect 版本必须支持精确一次投递(版本 3.3.0 或更高)。

Kafka Worker 的配置

所有 Kafka Connect Worker 都必须通过在 Worker 配置文件中设置以下属性来启用精确一次投递:

exactly.once.source.support=enabled

有关更多详细信息(例如,ACL 配置),请参阅官方 Kafka 文档

源连接器的配置

要为特定的源连接器启用精确一次投递,请在连接器配置中添加以下设置:

exactly.once.support=required

对于所有 Debezium 源连接器,还需要将附加设置 transaction.boundary 设置为 poll。但是,由于 poll 是默认值,因此除非被覆盖,否则不需要在配置中显式包含此设置。