我使用的是使用0.11.0.2客户端的spring-kafka 1.3.5。 我有2个分区。我的max.poll.records = 1。
我的问题是:假设我有2个节点/工作者(其并发性设置为1,因此每个节点中有一个使用者),这是慢工作者(可能需要5分钟来处理记录),两者目前都已关闭。当node-1(consumer-1)加入一个使用者组时,它会分配2个分区(p-1,p-2)。现在,consumer-1消耗来自p-1的消息。并且node-2(consumer-2)立即加入同一个消费者组。
是否有可能将p-1分配给consumer-2或kafka 知道consumer-1当前正在处理消息,因此它会分配 partition-2到consumer-2?如果发生这种情况,node-2可以进行相同的操作 来自p-1和消费者-1的消息(因为它还没有确认) 完成处理,当尝试提交它的偏移量时,会有一个 CommmitFailedException或抛出任何异常?
消费者可以在不再拥有的分区上调用syncCommits()吗? 是否会抛出异常?
答案 0 :(得分:1)
为消费者群体中的消费者分配分区的责任由消费者组织负责人负责,消费者组织领导者是消费者群体的协调者之一,而不是Kafka经纪人。作为组协调员的Kafka Broker将仅触发重新平衡,即通知消费者组长,新的消费者已加入该组,并且需要重新分配分区。
Kafka不会存储任何状态,例如当前正在处理哪些消息,只有它存储的内容是consumerGroup提交的主题中每个分区的偏移量。
要分配分区,Kafka有三种分区分配策略 - Range和RoundRobin以及Sticky Assignor。你可以在这里读更多关于它的内容。
范围分配器 - https://kafka.apache.org/10/javadoc/index.html?org/apache/kafka/clients/consumer/RangeAssignor.html
Round-Robin Assignor - https://kafka.apache.org/10/javadoc/org/apache/kafka/clients/consumer/RoundRobinAssignor.html
粘性指定者 - https://kafka.apache.org/10/javadoc/org/apache/kafka/clients/consumer/StickyAssignor.html
至于上面的两个问题,消费者2完全有可能获得分配的分区1,因此接收已经处理过的消息。如果你做一个手动偏移提交,是的,你应该收到一个CommitFailed Exception,当消费者1试图提交它的偏移时,无论它是否拥有P1。