1、什么是分区分配策略
在 kafka 中,存在两种分区分配策略,Range(默认)、RoundRobin (轮询)。 通过
partition.assignment.strategy 这个参数来设置。
Range strategy(范围分区)
Range 策略是对每个主题而言的,第一对同一个主题里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。假设我们有 10 个分区,3 个消费者,排完序的分区将会是 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;消费者线程排完序后将会是 C1-0, C2-0, C3-0。然后将 partitions 的个数除于消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。
RoundRobin strategy(轮询分区)
轮询分区策略是把所有 partition 和所有 consumer 线程都列出来,然后按照 hashcode 进行排序。最后通过轮询算法分配 partition给消费线程。如果所有 consumer 实例的订阅是一样的,那么 partition 会均匀分布。
在我们的例子里面,如果按照 hashCode 排序完的 topic partitions 组依次为 T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我们的消费者线程排序为 C1-0, C1-1, C2-0, C2-1,最后分区分配的结果为:
C1-0 将消费 T1-5, T1-2, T1-6 分区;
C1-1 将消费 T1-3, T1-1, T1-9 分区;
C2-0 将消费 T1-0, T1-4 分区;
C2-1 将消费 T1-8, T1-7 分区;
使用轮询分区策略必须满足两个条件
1. 每个主题的消费者实例具有一样数量的流
2. 每个消费者订阅的主题必须是一样的
2、什么时候会触发这个策略呢?
1. 同一个 consumer group 内新增了消费者。
2. 消费者离开当前所属的 consumer group,列如主动停机或者宕机。
3. topic 新增了分区, consuemr 的 rebalance 机制规定了一个 consumer group下的所有 consumer 如何达成一致来分配订阅 topic的每个分区。而具体如何执行分区策略,就是上面提到过的两种内置的分区策略。
3、谁来执行 Rebalance 以及管理 consumer 的 group 呢?
Kafka 提供了一个角色:coordinator(协调/调度)来执行对于consumer group的管理,当consumer group的第一个 consumer 启动的时候,它会去和kafka server确定谁是它们组的coordinator,之后该 group 的所有成员都会和该 coordinator 进行协调通信。
如何确定coordinator?
消费者向kafka集群中的任意一个broker发送一个GroupCoordinatorRequest 请求,服务端会返回一个负载最小的broker节点的id,并将该broker设置为coordinator。
消费端发⽣rebalance的过程是怎样的?
在 rebalance 之前,需要保证 coordinator 是已经确定好了的,整个 rebalance 的过程分为两个步骤,joinGroup 和 Synchronizing Group State。
joinGroup: 表明加入到 consumer group 中,在这一步中,所有的成员都会向 coordinator 发送 joinGroup 的请求。一旦所有成员都发送了 joinGroup 请求,那么 coordinator 会选择一个 consumer 担任 leader 角色,并把组成员信息和订阅信息发送消费者。

protocol_metadata: 序列化后的消费者的订阅信息
leader_id:消费组中的消费者,coordinator 会选择一个作为 leader,对应的就是 member_id
member_metadata:对应消费者的订阅信息
members:consumer group 中全部的消费者的订阅信息
generation_id:年代信息,类似于之前讲解zookeeper的时候的epoch是一样的,对于每一轮 rebalance,generation_id 都会递增。主要用来保护 consumer group。隔离无效的 offset 提交。也就是上一轮的 consumer 成员无法提交 offset 到新的 consumer group 中。
Synchronizing Group State:
完成分区分配之后,就进入了Synchronizing Group State阶段,主要逻辑是向 GroupCoordinator 发 送SyncGroupRequest 请求,并且处理 SyncGroupResponse响应,简单来说,就是 leader 将消费者对应的 partition 分配方案同步给 consumer group 中的所有 consumer。

每个消费者都会向 coordinator 发送 syncgroup 请求,不过只有 leader 节点会发送分配方案,其他消费者只是打打酱油而已。当 leader 把方案发给 coordinator 后来,coordinator 会把结果设置到 SyncGroupResponse 中。这样所有成员都知道自己应该消费哪个分区。
consumer group 的分区分配方案是在客户端执行的! Kafka 将这个权利下放给客户端主要是由于这样做可以有更好的灵活性。



收藏了,感谢分享