Kafka之Consumer Group的重平衡Rebalance

Kafka之Consumer Group的重平衡Rebalance

1.何为Rebalance

Rebalance就是一个完整的Consumer Group中的consumer实例在Broker中协调者的帮助下,就如何消费订阅topic分区达成共识的过程。

整个Rebalance的过程类似于JAVA中full GC的过程,需要stop the world,在rebalance的过程中,消费者是无法进行消息消费的,十分影响消费者的吞吐量。

这里的协调者即coordinator,每个broker都有一个coordinate组件,并且伴随着broker启动而被创建,它主要负责接收consumer提交的消费位移,然后转交给broker,同时也负责consumer的注册、成员管理记录等元数据的管理操作。

2.consumer如何确定管理自己的cordinate在哪个broker

实际上这个问题就是确定consumer的提交的数据属于哪个位移topic的分区。

主要是分为以下两个步骤:

第 1 步:确定由位移主题的哪个分区来保存该 Group 数据:partitionId=Math.abs(groupId.hashCode() % offsetsTopicPartitionCount)。

第 2 步:找出该分区 Leader 副本所在的 Broker,该 Broker 即为对应的 Coordinator。

3.Rebalance的弊端

开始提到了rebalance有点类似于java中的full GC需要STW,影响消费者消费的吞吐量,更为详细的,rebalance整个过程的弊端主要是以下几点

  1. STW,影响consumer端的TPS;
  2. rebalance的过程很慢,当consumer goup中有任何一次consumer的退出和加入,都需要进行rebalance,并且每次rebalance都需要涉及该group下的所有consumer;

其中比较经典的例子如下(摘自胡夕老师极客时间专栏)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34MlzQDb-1593139893002)(/Users/liyang206/Library/Application Support/typora-user-images/image-20200626103351487.png)]

目前退出了StickyAssignor的粘性分区分配策略,以此确保局部性分配原理,尽可能地在每次rebalance时都保留之前的分配方案,仅对退出分配管理的topic 分区进行重新分配。

4.Rebalance触发的时机

rebalance除了上述反复提到的当consumer group有成员数量变化时,会被触发。这是从consumer端来说的,那么对于broker端,当发生以下两种情况时,也会触发rebalance,本质上来说,这些情况的发生,都是因为破坏了原先topic分区的分配情况。

订阅主题数量发生变化

订阅主题的分区数发生变化

5.如何规避该规避的rebalance,从而提高整个kafka的效率

4.中所述的三种rebalance触发的时机,很明显关于topic以及topic分区的数量调整是少有发生,或者完全可以规避的。

实际生产环境中,更容易发生的是group中consumer实例数量的变化。关于consumer实例的增加,这显然是因为业务需要,不得不进行增加。我们需要关注的是如何保证consumer实例被踢出group的情况。

那么什么情况下,consumer会被视为可以被踢出group:

当 Consumer Group 完成 Rebalance 之后,每个 Consumer 实例都会定期地向 Coordinator 发送心跳请求,表明它还存活着。如果某个 Consumer 实例不能及时地发送这些心跳请求,Coordinator 就会认为该 Consumer 已经“死”了,从而将其从 Group 中移除,然后开启新一轮 Rebalance。Consumer 端有个参数,叫 session.timeout.ms,就是被用来表征此事的。该参数的默认值是 10 秒,即如果 Coordinator 在 10 秒之内没有收到 Group 下某 Consumer 实例的心跳,它就会认为这个 Consumer 实例已经挂了。可以这么说,session.timeout.ms 决定了 Consumer 存活性的时间间隔。

consumer端影响consumer实例是否活着的三个重要参数:

  1. session.timeout.ms,被用来表征间隔多长时间向cordinate发送心跳的。该参数的默认值是 10 秒,即如果 Coordinator 在 10 秒之内没有收到 Group 下某 Consumer 实例的心跳,它就会认为这个 Consumer 实例已经挂了。
  2. heartbeat.interval.ms,控制发送心跳请求频率的参数,这个值设置得越小,Consumer 实例发送心跳请求的频率就越高。频繁地发送心跳请求会额外消耗带宽资源,但好处是能够更加快速地知晓当前是否开启 Rebalance,
  3. max.poll.interval.ms:它限定了 Consumer 端应用程序两次调用 poll 方法的最大时间间隔。它的默认值是 5 分钟,表示你的 Consumer 程序如果在 5 分钟之内无法消费完 poll 方法返回的消息,那么 Consumer 会主动发起“离开组”的请求,Coordinator 也会开启新一轮 Rebalance。

你可能感兴趣的:(Kafka之Consumer Group的重平衡Rebalance)