是否仅对流(主题1->应用程序->主题2)“恰好一次”?

时间:2019-05-09 17:57:25

标签: java apache-kafka apache-kafka-streams

我有一个体系结构,其中有两个单独的应用程序。原始来源是sql数据库。 App1侦听CDC表以跟踪对该数据库中表的更改,对其进行规范化和序列化。它接收那些序列化的消息,并将其发送到Kafka主题。 App2侦听该主题,将消息改编为不同的格式,然后通过HTTP将这些改编的消息发送到其各自的目的地。

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

  

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

我们希望在出现故障的情况下增加错误处理,并且不能容忍重复事件,丢失事件或更改订单。鉴于上述架构,我们真正关心的是,仅一次应用于从App1到App2(我们独立的生产者和消费者)的消息

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

  

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

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

1 个答案:

答案 0 :(得分:1)

如果您使用的是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,以便开发人员只需几行代码即可轻松使用EOS(例如,在需要应用程序时自动进行状态管理)进行有状态操作(例如聚合或联接)。在阅读了文档之后,生产者/消费者<-> Kafka Streams之间的关系也许是您的困惑?

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

  

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

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

我希望有帮助。