让我们假设只有一个主题具有20个分区,而一个消费者组只有一个从该主题消费的消费者实例。
如果此消费者实例有20个线程,则重新平衡之后,Kafka将把每个分区分配给一个线程,这是理想的选择(一个线程分配给一个分区)
但是在这一点上;如果另一个具有20个线程的使用者实例添加到该使用者组会发生什么情况?
我猜这些选项会是这样;
1-不会发生重新平衡,第二个使用者保持空闲状态。 (因为20个线程已经足够用于20个分区)
2-发生重新平衡,并且将10个分区分配给了第一个使用者,而其他10个分区则分配给了第二个使用者。 (每个使用者10个线程将处于空闲状态)
实际上,第二种选择更理想。因为我们通过添加另一个实例来分割工作。
那么在这种情况下会发生哪种情况?卡夫卡能否顺利处理此案?还是添加另一个实例只是浪费?
编辑:我将“实例”一词用作微服务实例,而不是KafkaConsumer实例btw。
答案 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。 新实例中的第一个线程可能处于空闲状态,但是第二个可能开始处理数据。
根据有问题的新信息进行更新