spring-kafka 1.3.5环境下Kafka Rebalance相关问题咨询
针对你提到的Spring Kafka 1.3.5(对应Kafka客户端0.11.0.2)场景,我来逐个解答你的问题:
问题1:重平衡后的分区分配与偏移量提交问题
当node-2的consumer-2加入组时,必然会触发消费者组的重平衡——这是Kafka消费者组机制的核心规则,只要组内成员数量变化,不管现有消费者是否在处理消息,都会启动重平衡流程,重新分配所有分区。
是否存在p-1被分配给consumer-2的可能?
当然有可能。你有2个消费者和2个分区,不管用默认的RangeAssignor还是RoundRobinAssignor分配策略,最终都会是每个消费者分到1个分区。至于p-1最终归属consumer-1还是consumer-2,取决于消费者ID的排序、分区序号等细节,但两种结果都完全合理。这里要注意:Kafka不会感知到consumer-1正在处理消息,重平衡的分区分配逻辑只依赖当前组内的成员列表和分区列表,和消费者的处理状态无关。若p-1被分配给consumer-2,consumer-2是否会拉取到同一条未确认的消息?
是的。因为consumer-1还没提交这条消息的偏移量,consumer-2接手p-1后,会从该分区最后一次成功提交的偏移量位置开始拉取数据——也就是consumer-1正在处理的这条未确认消息的起始位置,所以consumer-2会拿到同一条消息。这属于Kafka重平衡场景下的正常重复消费情况,通常需要业务层做幂等处理来避免影响。当consumer-1处理完成并尝试提交偏移量时,是否会抛出异常?
会抛出CommitFailedException。重平衡完成后,consumer-1已经不再是p-1的合法所有者了,Kafka集群在接收偏移量提交请求时,会验证提交者是否是当前分区的归属消费者,一旦发现consumer-1没有p-1的所有权,就会拒绝提交并抛出该异常。
问题2:对已失去所有权的分区调用syncCommits()的结果
当消费者不再拥有某个分区的所有权时,调用syncCommits()(或者异步提交的asyncCommits())会抛出CommitFailedException。
这是因为Kafka的偏移量提交机制有严格的权限校验:只有当前被分配了该分区的消费者,才能提交该分区的偏移量。如果消费者在重平衡后失去了分区所有权,再尝试提交该分区的偏移量,集群会直接返回错误,客户端就会抛出这个异常,提示类似“Cannot commit offsets because the consumer is not part of the group for the partition”的信息。
内容的提问来源于stack exchange,提问作者Siva praneeth Alli

