线上Kafka突发rebalance异常,如何快速解决? (2)

SyncGroup 请求的主要目的,就是让协调者把领导者制定的分配方案下发给各个组内成员。当所有成员都成功接收到分配方案后,消费者组进入到 Stable 状态,即开始正常的消费工作。

什么时候会发生rebalance?

前面我们已经说到,rebalance 其实就是对 partition 进行重新分配。那么什么时候会发生 rebalance 呢?其实在以下三种情况下,会触发 rebalance:

订阅 Topic 的分区数发生变化。

订阅的 Topic 个数发生变化。

消费组内成员个数发生变化。例如有新的 consumer 实例加入该消费组或者离开组。

订阅Topic的分区数发生变化

简单地说,就是之前 topic 有 10 个分区,现在变成了 20 个,那么多出来的 10 个分区的数据就没人消费了。那么此时就需要进行重平衡,将新增的 10 个分区分给消费组内的消费者进行消费。所以在这个情况下,会发生重平衡。

订阅的Topic个数发生变化

简单地说,一个 consumer group 如果之前只订阅了 A topic,那么其组内的 consumer 知会消费 A topic 的消息。而如果现在新增订阅了 B topic,那么 kafka 就需要把 B topic 的 partition 分配给组内的 consumer 进行消费。这个分配的过程,其实也是一个 rebalance 的过程。

消费组内成员个数发生变化

我们都知道 kafka 中是以消费组(consumer group)的方式进行消费的,消费组内的消费者共同消费一个 topic 下的消息。而当消费组内成员个数发生变化,例如某个 consumer 离开,或者新 consumer 加入,都会导致消费组内成员个数发生变化,从而导致重平衡。

相比起之前的两个情况,这种情况在实际情况中更加常见。因为订阅分区数、以及订阅 topic 数都是我们主动改变才会发生,而组内消费组成员个数发生变化,则是更加随机的。

文章首发于【陈树义的博客】,点击跳转到原文《线上Kafka突发rebalance异常,如何快速解决?》

下面我们一起分析一下「消费组内成员个数发生变化」的几种情况:

新成员加入

组成员主动离开

组成员崩溃

新成员加入

新成员入组是指组处于 Stable 状态后,有新成员加入。如果是全新启动一个消费者组,Kafka 是有一些自己的小优化的,流程上会有些许的不同。我们这里讨论的是,组稳定了之后有新成员加入的情形。

当协调者收到新的 JoinGroup 请求后,它会通过心跳请求响应的方式通知组内现有的所有成员,强制它们开启新一轮的重平衡。具体的过程和之前的客户端重平衡流程是一样的。现在,我用一张时序图来说明协调者一端是如何处理新成员入组的。

组成员主动离开

何谓主动离组?就是指消费者实例所在线程或进程调用 close() 方法主动通知协调者它要退出。这个场景就涉及到了第三类请求:LeaveGroup 请求。协调者收到 LeaveGroup 请求后,依然会以心跳响应的方式通知其他成员,因此我就不再赘述了,还是直接用一张图来说明。

组成员崩溃

崩溃离组是指消费者实例出现严重故障,突然宕机导致的离组。它和主动离组是有区别的,因为后者是主动发起的离组,协调者能马上感知并处理。但崩溃离组是被动的,协调者通常需要等待一段时间才能感知到,这段时间一般是由消费者端参数 session.timeout.ms 控制的。

也就是说,Kafka 一般不会超过 session.timeout.ms 就能感知到这个崩溃。当然,后面处理崩溃离组的流程与之前是一样的,我们来看看下面这张图。

疑惑

在许多文章中,它们会加多了一个 rebalance 场景,即:「重平衡时协调者对组内成员提交位移的处理」。其实这个要说是 rebalance 场景,有点牵强。我们先来了解下这个场景究竟是什么情况。

正常情况下,每个组内成员都会定期汇报位移给协调者。当重平衡开启时,协调者会给予成员一段缓冲时间,要求每个成员必须在这段时间内快速地上报自己的位移信息,然后再开启正常的 JoinGroup/SyncGroup 请求发送。还是老办法,我们使用一张图来说明。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwwyd.html