您的位置:首页 > 其它

Kafka系列(17)消费者组重平衡能避免吗

2019-07-16 14:47 881 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_18522601/article/details/96128859

Rebalance就是让一个Consumer Group下所有的Consumer实例就如何消费订阅主题的所有分区达成共识的过程。

在Rebalance过程中,所有Consumer实例共同参与,在协调者组件的帮助下,完成订阅主题分区的分配。

但是,在整个过程中,所有实例都不能消费任何消息,因此它对Consumer的TPS影响很大。

 

所谓协调者,在Kafka中对应的术语是Coordinator,它专门为Consumer Group服务,负责为Group执行Rebalance以及提供位移管理和组成员管理等。

 

Consumer端应用程序在提交位移时,其实是向Coordinator所在的Broker提交位移。同样地,当

Consumer应用程序启动时,也是向Coordinator所在的Broker发送各种请求,然后由Coordinator

负责执行消费者组的注册、成员管理记录等元数据管理操作。

 

所有Broker在启动时,都会创建和开启相应的Coordinator组件。也就是,所有Broker都有各自的Coordinator

组件。Cosumer Group如何确定为它服务的Coordinator在哪台Broker上,答案就在Kafka内部位移主题——

consumer_offsets身上

 

Kafka为某个Consumer Group 确定Coordinator所在的Broker算法有两个步骤:

第一步:确定由位移主题的哪个分区来保存该Group数据:

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

首先,Kafka会计算该Group的group.id参数的哈希值。比如,你有个Group的group.id设置成了

“test-group”,那么它是hashcode值就应该是627841412.其次,Kafka会计算_consumer_offsets的分区数,通常是50

个分区,之后将刚才那个哈希值对分区数进行取模求绝对值,即 abs(627841414%50)=12.此时,我们就知道了位移主题的分区12负责保存这个Group的数据。有了分区号,算法的第二步就变得很简单了,我们只要找出位移分区12的leader副本在哪个Broker上就可以,这个Broker,我们要找的Coordinator.

知晓这个算法的意义在于,它能够帮助我们解决定位问题,当Consumer Group出现问题,需要快速排查Broker端日志,

我们能够根据这个算法准确定位Coordinator定位对应的Broker.

 

Rebalance的弊端:

   1 Rebalance影响了Consumer端TPS

   2 Rebalance很慢

    3 Rebalance效率不高,每次Rebalance时,Group所有成员都参与进来,没考虑局部性原理。

 

一个Group下有10个成员,每个成员平均消费5个分区,假设有个成员退出,此时需要重新开启新一轮的Rebalance,

把这个成员之前的负责的5个分区转移给其他成员。需要升级到0.11.0.0,但是有些bug

 

在真实的业务场景中,很多Rebalance都是计划外的或者说是不必要的。

Rebalance发生的时间有三个:

  组成员数量发生变化

   订阅主题数量发生变化

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

后两个都是运维的主动操作,它所引发的Rebalance大都不可避免。

Consumer实例增加的情况很好理解,当我们启动一个配置有相同的group.id值的Consumer程序时,实际上就是向这个

Group添加一个新的Consumer实例。此时,Coordinator会接纳这个新实例,将其加入到组中,并重新分配分区。

增加Consumer实例的操作都是计划内的,可能是出于增加Tps或提高伸缩性的需要。总之,它不属于我们要规避的那类不必要的Rebalance.

 

当Consumer  Group完成Rebalance之后,每个Consumer实例都会定期向Coordinator发送心跳请求,表明它还存活着。

Consumer端有个从参数,叫session.timeout.ms,就是被用来表征此事的。该参数默认值是10秒

即如果Coordinator在10秒之内没有收到某个Group下某Consumer实例的心跳,它就会认为这个Consumer

实例已经挂了。可以说,session.timeout.ms决定了Consumer存活性的时间间隔。

 

Consumer还提供了了允许你控制发送心跳请求频率的参数,就是heartbeat.interval.ms 这个值设置得越小,

Consumer实例发送心跳请求的频率就越高。频繁发送心跳请求会额外请求消耗带宽资源,但好处是能够更快速知晓当前是否开启Rebalance,因此,目前Coordinator通知各个Consumer实例开启Rebalance的方法,就是讲REBALANCE_NEEDED标志封装进心跳请求的响应体中。

 

除了两个参数,Consumer端还有一个参数,用于控制Consumer实际消费能力对Rebalance的影响,即max.poll.interval.ms

它限定了Consumer端应用程序两次调用poll方法的最大时间间隔。默认是5分钟,表示你的Consumer程序如果在5分钟之内无法消费完poll方法返回的消息,那么Consumer会主动发起离开组的请求,Coordinator也会开启新一轮的Rebalance.

 

第一类非必要的玩Rebalance是因为未能及时发送心跳,导致Consumer被踢出Group而引发的

    设置session.timeout.ms=6s

    设置heartbeat.interval.ms=2s

   要保证Consumer实例在被判定为dead之前,能够发送至少3轮心跳请求。即session.timeout.ms>=3*heartbeat.interval.ms

第二类非必要Rebalance是Consumer消费时间过长导致的。

      要为你的业务逻辑留下充足的时间,这样,Consumer就不会因为处理这些消息的时间太长而引发Rebalance

还有其他原因:

      频繁出现Full GC 导致长时间的停顿

 

 

 

 

 

 

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: