首页 > 解决方案 > “恰好一次”仅适用于流(topic1 -> app -> topic2)吗?

问题描述

我有一个架构,我们有两个独立的应用程序。原始来源是一个sql数据库。App1 侦听 CDC 表以跟踪对该数据库中表的更改、规范化和序列化这些更改。它获取这些序列化消息并将它们发送到 Kafka 主题。App2 监听该主题,将消息调整为不同的格式,并通过 HTTP 将这些调整后的消息发送到各自的目的地。

所以我们的流式架构看起来像:

SQL(CDC事件)-> App1(规范化事件)-> Kafka -> App2(使事件适应端点)-> 各种端点

我们希望在发生故障时添加错误处理,并且不能容忍重复事件、丢失事件或更改顺序。鉴于上述架构,我们真正关心的是,exact-once 应用于从 App1 到 App2 的消息(我们独立的生产者和消费者)

我正在阅读的所有内容以及我发现的事务性 api 的每个示例都指向“流”。看起来 Kafka 流 api 是为单个应用程序设计的,该应用程序从 Kafka 主题中获取输入,进行处理,然后将其输出到另一个 Kafka 主题,这似乎不适用于我们对 Kafka 的使用。以下是Confluent 文档的摘录:

现在,流处理只不过是对 Kafka 主题的读-处理-写操作;消费者从 Kafka 主题读取消息,一些处理逻辑转换这些消息或修改处理器维护的状态,生产者将生成的消息写入另一个 Kafka 主题。恰好一次流处理只是一次执行读取-处理-写入操作的能力。在这种情况下,“得到正确答案”意味着不会丢失任何输入消息或产生任何重复输出。这是用户期望从恰好一次流处理器中获得的行为。

我正在努力思考我们如何在 Kafka 主题中使用完全一次,或者如果 Kafka 的完全一次是为非“流式”用例而构建的。我们是否必须建立自己的重复数据删除和容错能力?

标签: javaapache-kafkaapache-kafka-streams

解决方案


如果您使用的是 Kafka 的 Streams API(或其他支持使用 Kafka 进行精确一次处理的工具),那么 Kafka 的精确一次语义 (EOS) 将涵盖所有应用程序:

topic A --> App 1 --> topic B --> App 2 --> topic C

在您的用例中,一个问题是初始 CDC 步骤是否也支持 EOS。也就是说,你必须要问一个问题:涉及到哪些步骤,EOS涵盖了所有步骤?

在以下示例中,当(且仅当)初始 CDC 步骤也支持 EOS 时,端到端支持 EOS,就像数据流的其余部分一样。

SQL --CDC--> topic A --> App 1 --> topic B --> App 2 --> topic C

如果您使用 Kafka Connect 进行 CDC 步骤,那么您必须检查您使用的连接器是否支持 EOS 是或否。

我正在阅读的所有内容以及我发现的事务性 api 的每个示例都指向“流”。

Kafka 生产者/消费者客户端的事务 API 为 EOS 处理提供了原语。位于生产者/消费者客户端之上的 Kafka Streams 使用此功能来实现 EOS,开发人员只需几行代码即可轻松使用它(例如在应用程序需要时自动处理状态管理)进行有状态的操作,如聚合或连接)。也许生产者/消费者之间的关系 <-> Kafka Streams 是您阅读文档后的困惑?

当然,您也可以在开发应用程序时使用底层的 Kafka 生产者和消费者客户端(使用事务 API)“构建自己的”,但这需要更多的工作。

我正在努力思考我们如何在 Kafka 主题中使用完全一次,或者如果 Kafka 的完全一次是为非“流式”用例而构建的。我们是否必须建立自己的重复数据删除和容错能力?

不确定“非流式”用例是什么意思。如果您的意思是,“如果我们不想使用 Kafka Streams 或 KSQL(或其他可以从 Kafka 读取数据来处理数据的现有工具),我们需要做什么来在我们的应用程序中实现 EOS?”,那么答案是“是的,在这种情况下,您必须直接使用 Kafka 生产者/客户端,并确保您对它们所做的任何事情都能正确实施 EOS 处理。” (而且因为后者比较困难,所以这个 EOS 功能被添加到了 Kafka Streams 中。)

我希望这会有所帮助。


推荐阅读