首页 > 解决方案 > Kafka Streams 在监听具有多个分区的主题时如何确保处理所有相关数据?

问题描述

我想知道如何将 Kafka Streams 分配给主题分区以供阅读。据我了解,每个Kafka Stream Thread都是一个Consumer(并且Stream有一个Consumer Group)。所以我猜消费者被随机分配到分区。

但是,如果我有多个要加入的输入主题,它是如何工作的?

例子:

主题 P包含人员。它有两个分区。消息的键是 person-id,所以属于一个人的每条消息总是在同一个分区中结束。

主题 O包含订单。它有两个分区。假设键也是(订购某物的人的)人名。所以在这里,属于一个人的每个订单消息也总是在同一个分区中结束。

现在我有一个流,它从两个主题中读取并计算每个人的所有订单并将其写入另一个主题(其中消息还包括人名)。

主题 P中的数据:

分区 1 : "hans, id=1","maria, id=3"

分区 2"john, id=2"

主题 O中的数据:

分区 1 : "person-id=2, pizza","person-id=3, cola"

分区 2"person-id=1, lasagne"

现在我开始两个流。

那么这可能会发生:

流 1分配给主题 P 分区 1主题 O 分区 1

流 2分配给主题 P 分区 2主题 O 分区 2

这意味着永远不会计算for的顺序 ,因为为此流将需要使用主题 P 分区 1主题 O 分区 2lasagnehans

那么如何处理这个问题呢?我想流需要以某种方式处理彼此相关的数据是相当普遍的。因此,必须确保相关数据(此处:hanslasagne)由同一流处理。

我知道如果只有一个流或主题只有一个分区,则不会发生此问题。但我希望能够同时处理消息。

谢谢

标签: apache-kafkastreamapache-kafka-streams

解决方案


您的用例是KStream-KTable 连接,其中 KTable 存储用户的信息,KStream 是订单流,因此这两个主题co-partitioned必须具有相同的分区号并由相同的键和分区器分区。如果您使用person-id作为 kafka 消息的 key,并且使用相同的 Partitioner,则不必担心这种情况,因为它们位于相同的分区号上。

更新:正如 Matthias 指出的,每个 Stream Thread 都有自己的 Consumer 实例。


推荐阅读