按键加入多个Kafka主题

时间:2017-03-26 09:52:35

标签: apache-kafka kafka-consumer-api

如何编写以可扩展方式加入多个Kafka主题的消费者?

我的主题是使用密钥发布事件,第二个主题是使用相同的密钥发布与第一个主题的子集相关的其他事件。我想编写一个订阅这两个主题的消费者,并对两个主题中出现的子集执行一些其他操作。

我可以轻松地与单个消费者一起完成此操作:从两个主题中读取所有内容,在本地维护状态,并在读取给定键的两个事件时执行操作。但我需要扩大规模的解决方案。

理想情况下,我需要将主题绑定在一起,以便以相同的方式对它们进行分区,并将分区同步分配给使用者。我怎么能这样做?

我知道Kafka Streams将主题连接在一起,以便将密钥分配给相同的节点。他们是如何做到的呢?附:我不能使用Kafka Streams,因为我使用的是Python。

1 个答案:

答案 0 :(得分:3)

你使用Python太糟糕了 - Kafka Streams非常适合:)

如果你想手动执行此操作,则需要实现自己的PartitionAssignor - 实现必须确保分区在分配中共存:假设每个主题有4个分区(让我们称它们为A和B),而不是分区A_0和B_0必须分配给同一个消费者(也是A_1和B_1,......)。

我希望Python使用者允许您通过配置参数partition.assignment.strategy指定自定义分区指定者。

这是PartitionAssignor Kafka Streams使用的:https://github.com/apache/kafka/blob/trunk/streams/src/main/java/org/apache/kafka/streams/processor/internals/StreamPartitionAssignor.java

Streams使用任务的概念 - 任务获得分配了相同分区号的不同主题的分区。 Streams还尝试进行“粘性赋值” - 即,如果可能的话,不要在重新平衡的情况下移动任务(以及分区)。因此,每个消费者在重新平衡元数据中对其“旧任务”进行编码。

基本上,对每个活着的消费者调用方法#subscription()。它将向消费者发送消费者的订阅信息(即消费者想要订阅的主题)以及可选的元数据。

在第二步中,消费者组的领导者将在#assign()内计算实际分配。负责经纪人在重新平衡的第一阶段收集#subscription()给出的所有信息,并将其交给#assign()。因此,领导者获得整个组的全局概览,从而可以确保以共处的方式分配分区。

在最后一步中,经纪人从领导者处收到计算出的分配,并将其广播给该组的所有消费者。这将导致每个消费者都呼​​叫#onAssignment()

这也可能有所帮助: