将新的多线程使用者添加到组中时是否发生重新平衡

时间:2019-02-24 06:14:49

标签: java multithreading apache-kafka kafka-consumer-api

让我们假设只有一个主题具有20个分区,而一个消费者组只有一个从该主题消费的消费者实例。

如果此消费者实例有20个线程,则重新平衡之后,Kafka将把每个分区分配给一个线程,这是理想的选择(一个线程分配给一个分区)

但是在这一点上;如果另一个具有20个线程的使用者实例添加到该使用者组会发生什么情况?

我猜这些选项会是这样;

1-不会发生重新平衡,第二个使用者保持空闲状态。 (因为20个线程已经足够用于20个分区)

2-发生重新平衡,并且将10个分区分配给了第一个使用者,而其他10个分区则分配给了第二个使用者。 (每个使用者10个线程将处于空闲状态)

实际上,第二种选择更理想。因为我们通过添加另一个实例来分割工作。

那么在这种情况下会发生哪种情况?卡夫卡能否顺利处理此案?还是添加另一个实例只是浪费?

编辑:我将“实例”一词用作微服务实例,而不是KafkaConsumer实例btw。

2 个答案:

答案 0 :(得分:1)

在这里添加另一个Kafka使用者没有用。第二个使用者中的所有线程将保持空闲状态。
一个分区只能分配给一个使用者。虽然,事实并非如此。一个使用者可以从n个分区读取数据。
尽管我不会说增加第二个消费者完全是浪费。您的第二个消费者将充当HA。万一您的第一个消费者应用程序死了,第二个消费者应用程序将开始从Kafka获取数据。

答案 1 :(得分:1)

如何分配主题的分区取决于PartitionAssignor,它由使用者组的组长使用。 加入小组的第一位消费者成为领导者。如果新使用者加入了已经在运行的小组, 使用者Leader根据其PartitionAssignor将分区分配给该组中的特定使用者。

您可以使用PartitionAssignor来设置partition.assignment.strategy。默认值为org.apache.kafka.clients.consumer.RangeAssignor。 如果要更改组的分​​配策略,则可以使用其他策略或实施自定义策略。

如果您转到RangeAssignor https://kafka.apache.org/10/javadoc/org/apache/kafka/clients/consumer/RangeAssignor.html的javadoc,则可以找到以下内容:

  

范围分配器按主题工作。   对于每个主题,我们以数字顺序排列可用分区,并以字典顺序排列使用者。   然后,我们将分区数除以使用者总数,以确定分配给每个使用者的分区数。   如果它没有均匀划分,那么前几个消费者将有一个额外的划分。   例如,假设有两个使用者C0和C1,两个主题t0和t1,并且每个主题都有3个分区,从而得出分区t0p0,t0p1,t0p2,t1p0,t1p1和t1p2。   分配为:C0:[t0p0,t0p1,t1p0,t1p1] C1:[t0p2,t1p2]

如果是您的情况RangeAssignor),您不知道新线程是否空闲。 例如,它取决于获得的消费者ID。 新实例中的第一个线程可能处于空闲状态,但是第二个可能开始处理数据。

根据有问题的新信息进行更新