面试题答案
一键面试分区分配策略
- Range 策略
- 原理:将主题的分区按照顺序排列,然后根据消费者数量对分区进行平均分配。例如,有 10 个分区(P0 - P9)和 3 个消费者(C0、C1、C2),首先计算每个消费者平均分配的分区数为
10 / 3 = 3
(向下取整),余数为10 % 3 = 1
。那么 C0 会分配到 P0 - P2,C1 分配到 P3 - P5,C2 分配到 P6 - P8,剩下的 P9 再分配给 C0。 - 缺点:如果每个主题的分区数不能被消费者数整除,可能会导致部分消费者负载过重。例如上述例子中 C0 比 C1 和 C2 多一个分区。而且如果多个主题使用 Range 策略,对于同一个消费者可能会出现负载不均衡,因为不同主题的分区数和消费者数关系不同。
- 原理:将主题的分区按照顺序排列,然后根据消费者数量对分区进行平均分配。例如,有 10 个分区(P0 - P9)和 3 个消费者(C0、C1、C2),首先计算每个消费者平均分配的分区数为
- Round Robin 策略
- 原理:将所有主题的分区组成一个列表,然后按照消费者的顺序依次循环分配。例如,有两个主题 T1(包含 P0 - P2)和 T2(包含 P3 - P5),三个消费者 C0、C1、C2。首先将所有分区按顺序排列为 [P0, P1, P2, P3, P4, P5],然后 C0 分配到 P0、P3,C1 分配到 P1、P4,C2 分配到 P2、P5。
- 优点:在多个主题的情况下,能更均匀地分配分区,避免某个消费者在多个主题下都负载过重。
- 缺点:如果消费者订阅的主题集合差异较大,可能会出现不合理分配。比如某个消费者只订阅了一个主题,而其他消费者订阅了多个主题,采用 Round Robin 策略可能导致只订阅一个主题的消费者分配到其他主题分区,造成资源浪费。
- Sticky 策略
- 原理:尽量保持现有分区分配方案不变,只有在必要时(如消费者新增或减少)才重新分配。重新分配时,会优先将原本分配给某个消费者的分区再次分配给它。例如,原本 C0 分配到 P0、P1,C1 分配到 P2、P3。当新增一个消费者 C2 时,Sticky 策略会尝试尽量让 C0 保留 P0、P1,然后从 C1 的 P2、P3 中分配一个给 C2。
- 优点:减少不必要的重新分配,降低网络开销和数据处理的中断。特别是在消费者数量变化频繁的场景下,能有效提高系统稳定性和效率。
Consumer 感知集群变化并重新分配分区
- 使用 Kafka 的心跳机制
- 心跳发送:消费者定期向 Kafka 集群中的 Group Coordinator(组协调器)发送心跳请求,以表明自己仍然存活。心跳请求间隔由
heartbeat.interval.ms
配置参数控制,默认值为 3000 毫秒。 - 心跳检测:Group Coordinator 会根据是否收到消费者的心跳来判断消费者是否存活。如果在
session.timeout.ms
配置的时间内(默认值为 10000 毫秒)没有收到某个消费者的心跳,Group Coordinator 会认为该消费者已死亡。
- 心跳发送:消费者定期向 Kafka 集群中的 Group Coordinator(组协调器)发送心跳请求,以表明自己仍然存活。心跳请求间隔由
- 消费者新增或减少
- 消费者新增:当有新的消费者加入 Consumer Group 时,它会向 Group Coordinator 发送 JoinGroup 请求。Group Coordinator 收到请求后,会触发一次重新平衡。所有消费者都会收到重新平衡的通知,然后它们会再次向 Group Coordinator 发送 JoinGroup 请求,Group Coordinator 根据分区分配策略重新分配分区,并通过 SyncGroup 响应将新的分区分配方案告知各个消费者。
- 消费者减少:如前文所述,当 Group Coordinator 检测到某个消费者死亡(未按时收到心跳),会触发重新平衡。同样,所有存活的消费者会收到重新平衡通知,通过 JoinGroup 和 SyncGroup 流程重新分配分区。
- 主题分区变化
- 分区新增:当 Kafka 主题新增分区时,Group Coordinator 会感知到这一变化。然后它会触发 Consumer Group 的重新平衡,所有消费者通过 JoinGroup 和 SyncGroup 流程,按照分区分配策略重新分配新增的分区。
- 分区删除:虽然 Kafka 一般不支持直接删除分区,但在某些特殊情况下(如使用工具强制删除等),如果分区被删除,Group Coordinator 同样会触发重新平衡,消费者会重新分配剩余的分区,确保消费的完整性。