当前位置:   article > 正文

Kafka Rebalance详解

kafka rebalance

1.rebalance概览

rebalance中文含义为再平衡。它本质上是一组协议,它规定了一个 consumer group 是如何达成一致来分配订阅 topic 的所有分区的。比方说Consumer Group A 有3个consumer 实例,它要消费一个拥有6个分区的topic,每个consumer消费2个分区,这就是rebalance。
rebalance是相对于consumer group 而言,每个consumer group会从kafka broker中选出一个作为组协调者(group coordinator)。coordinator负责对整个consumer group的状态进行管理,当有触发rebalance的条件发生时,促使生成新的分区分配方案。

2.rebalance触发条件

rebalance触发的条件有三个:

  • consumer group成员发生变更,比方说有新的consumer实例加入,或者有consumer实例离开组,或者有consumer实例发生奔溃。
  • consumer group订阅的topic数发生变更,这种情况主要发生在基于正则表达式订阅topic情况,当有新匹配的topic创建时则会触发rebalance。
  • consumer group 订阅的topic分区数发生变更。

其实无论哪种触发条件,我们可以发现根本原因还是因为topic 中partition或者consumer实例发生了变更。

3.rebalance分区分配策略

分区分配策略决定了将topic中partition分配给consumer group中consumer实例的方式。

可以通过消费者客户端参数partition.assignment.strategy来设置消费者与主题之间的分区分配策略

kafka新版本提供了三种rebalance分区分配策略:

  • range
  • round-robin
  • sticky

range 分配策略的原理是按消费者总数和分区总数进行整除运算来获得一个跨度,然后将分区按照跨度进行平均分配,以保证分区尽可能平均的分配给所有的消费者。

假设 n = 分区数/消费者数量,m= 分区数%消费者数量,那么前m个消费者每个分配n+1个分区,后面的(消费者数量-m)个消费者每个分配n个分区。

round-robin分配策略是将消费者组内所有主题的分区按照字典序排序,然后通过轮询的方式逐个将分区一次分配给每个消费者。

sticky分配策略是从0.11.x版本开始引入的分配策略,它主要有两个目的:

(1)分区的分配要尽可能均匀。

(2)分区的分配尽可能与上次分配的保持相同。

当两者发生冲突时,第一个目标优于第二个目标。sticky具体实现要比上面两种要复杂的多。

我们以一个具体的例子来说明。

假设消费者组内有3个消费者(C0、C1、C2),他们都订阅了4个主题(t0、t1、t2、t3),并且每个主题有两个分区。也就是说,整个消费者组订阅了t0p0、t0p1、t1p0、t1p1、t2p0、t2p1、t3p0、t3p1 8个分区。最终的分配结果为

消费者C0:t0p0、t1p1、t3p0
消费者C1:t0p1、t2p0、t3p1
消费者C2:t1p0、t2p1
  • 1
  • 2
  • 3

这看上去似乎与round robin分配策略相同,事实上并不是这样。假设此时C1脱离了消费者组,那么消费者组就会执行rebalance,进而消费分区会重新分配。如果采用round robin策略,那么此时的分配结果如下

消费者C0:t0p0、t1p0、t2p0、t3p0
消费者C2:t0p1、t1p1、t2p1、t3p1
  • 1
  • 2

如果采用sticky分配策略,那么分配结果为

消费者C0:t0p0、t1p1、t3p0、t2p0
消费者C2:t1p0、t2p1、t0p1、t3p1
  • 1
  • 2

可以看到分配结果中保留了上一次分配中对消费者C0和C2的所有的分配结果,并将原来的消费者C1的负担分配给了剩余的两个消费者C0和C1,最终C0和C2的分配还保持了平衡。

4.rebalance协议

前面提到。rebalance本质上是一组协议,consumer group和coordinator使用这组协议共同完成consumer group的rebalance。kafka新版本提供了下面5个协议来处理Rebalance

  • JoinGroup请求:consumer请求加入组
  • SyncGroup请求:group leader把分配方案同步更新到组内所有成员中。
  • Heartbeat请求:consumer定期向coordinator汇报心跳表明自己依然存活。
  • LeaveGroup请求:consumer主动通知coordinator自己将要离开consumer group。
  • DescribeGroup请求:查看组的所有的所有信息,包括成员信息、协议信息、分配方案、以及订阅信息等。该请求主要供管理员使用,coordinator不使用该请求实现rebalance。

rebalance 过程中, coordinator 要处理 consumer 发过来的 JoinGroup 和SyncGroup 请求 。当consumer 主动离组时会发送 LeaveGroup 请求给 coordinator

在成功 rebalance 之后,组内所有 consumer 都需要定期地向 coordinator 发送 Heartbeat 请求,而每个 consumer 也是根据 Heartbeat 请求的响应中是否包含 REBALANCE_IN_PROGRESS判断当前 group 开启了新一轮 rebalance。

5.rebalance流程

consumer group在执行rebalance之前必须首先确认coordinator在哪个broker上。并创建与该broker通信的socket连接。确定 coordinator 的算法与确定 offset 被提交到consumer offsets 目标分区的算法是相同的 算法如下:

  • 计算 Math.abs(groupID .hash Code) % offsets. topic.num. partitions 参数值(默认是 50) ,假设是 10
  • 寻找__consumer_offsets 分区 10 leader 副本所在的 broker ,该 broker 即为这group的coordinator

成功连接 coordinator 之后便可以执行 rebalance 操作, 目前 rebalance 主要分为两步:加入组和同步更新分配方案

  • 加入组:consumer group中所有consumer实例向coordinator发送JoinGroup请求。当收集全JoinGroup请求,coordinator从中选择一个consumer group作为group的leader,并把所有成员信息以及他们订阅的topic信息发送给leader。需要注意的是leader是consumer group中的一个consumer实例,而coordinator为集群的一个broker。是leader而不是coordinator负责为整个consumer group成员制定分配方案。
  • 同步更新分配方案:这一步leader开始制定分配方案,即根据前面提到的分配策略,决定哪个consumer消费哪些topic的哪些分区,一旦分配完成,leader会将分配方案封装进SyncGroup请求发送给coordinator。值得注意的是,组内所有成员都会发送SyncGroup请求,不过只有leader发送的请求中包含分配方案。coordinator收到分配方案后把属于每个consumer的分配方案单独抽取出来做作为SyncGroup请求的response返回给各个consumer。

下图分别描述了加入组和同步分配方案的流程。
rebalance加入组流程

rebalance同步分配方案流程

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号