保障效率与可用,分析Kafka的消费者组与Rebalance机制-CSDN博客

在这里插入图片描述
我们上一期从可靠性分析了消息可靠性方面来分析Kafka的机制与原理知晓了Kafka为了保障消息不丢失、不重复所作出的种种设计。今天我们来讲关于Kafka在消费端所作出的一些机制与原理

作者简介战斧从事金融IT行业有着多年一线开发、架构经验爱好广泛乐于分享致力于创作更多高质量内容
本文收录于 kafka 专栏有需要者可直接订阅专栏实时获取更新
高质量专栏 云原生RabbitMQSpring全家桶 等仍在更新欢迎指导
Zookeeper Redis dubbo docker netty等诸多框架以及架构与分布式专题即将上线敬请期待


一、消费者组概念

我们其实在很多MQ组件种都有消费者组的概念在Kafka中也不例外。消费者组与Kafka的Rebalance机制是保障Kafka消息消费效率与可用性的重要手段。
在这里插入图片描述
我们可以把多个消费者合成一个消费者组Group每个消费者组可以消费一个或多个主题的消息

二、消费者组的作用

1. 分区分配策略

消费者组是Kafka中实现消息分发与负载均衡的重要机制它可以分摊消息的处理压力并提高消息的处理效率和可用性。消费者组中的每个消费者可以独立消费分配给该消费者组的消息在消费过程中消费者不会相互干扰不会重复消费同一条消息也不会漏掉任何一条消息。

Kafka的消费者组工作流程如下图所示
在这里插入图片描述

如上图某个Topic里有两个分区而我们的消费者组有两个消费者那么两个消费者就会各自订阅一个分区互不干扰。

当然有些同学会问你这里正好是两个分区、两个消费者那如果两边数量不一样呢

那么这就涉及到partition的分配问题即确定那个partition由哪个consumer来消费。
Kafka有三种分配策略一是roundrobin一是range还有一个StickyAssignor策略

  1. range策略
    Range是对每个Topic而言的即一个Topic一个Topic分首先对同一个Topic里面的分区按照序号进行排序并对消费者按照字母顺序进行排序。然后用Partitions分区的个数除以消费者线程的总数来决定每个消费者线程消费几个分区。每个消费者消费的分区是连续的如果除不尽那么前面几个消费者线程将会多消费一个分区
    在这里插入图片描述

但其弊端也比较明显排名靠前的消费者压力比较大如果该消费者组仅订阅1个Topic还好如果订阅多个主题前面的消费者压力就明显更大了如下图消费者1订阅8个分区而消费者3订阅6个分区

在这里插入图片描述

  1. roundrobin策略
    为了解决排名靠前的消费者压力过大的问题一种思路就是全局考虑把一个消费者组消费的所有分区都罗列出来并字典序排序然后再轮询的分给消费者我们按照上面的例子大概的分配示意图如下
    在这里插入图片描述
    如图当Topic1的分区10被分给消费者1后Topic2的分区1就分配给消费者2了。那这样最后看到每个消费都订阅了7个分区很平均了。但就完美了吗非也我们上面看的都是以消费者组为单位的订阅行为但是别忘记消费者组里面的某个消费者可能还有其他的任务如下
    在这里插入图片描述
    上面的消费者3除了作为消费者组的一份子承接了Topic1和Topic2的部分分区它还订阅了Topic3那么消费者3的压力明显就大的太多了
  2. StickyAssignor策略
    该策略的实现更加复杂它要求从一种更加全局的视角来分配充分考虑到消费者组内每个消费者组的实际订阅数。它有两个目的
    分区的分配要尽可能的均匀分配给消费者者的主题分区数最多相差一个
    分区的分配尽可能的与上次分配的保持相同。
    至于其具体原理可以参考官方文档这里不继续深入探讨了

2. 分配原理

我们上面说了几种分区分配的方案这种分配任务的方式被称为协作分区(cooperative partitioning)。在cooperative partitioning过程中那么协作分区的结果谁来保存呢其实是组协调器Group CoordinatorKafka通过组协调器来保存消费者间的划分实现了消费者组的自动管理使得消费者组可以根据实际情况动态地扩容、缩容。

当然这里需要介绍下协调器的概念每一个Kafka集群都有若干个Coordinator它们分别负责不同的任务。目前Kafka中的Coordinator主要有以下几种

  • Group Coordinator负责管理消费者组包括新增、删除和重平衡操作。

  • Transaction Coordinator负责事务的管理包括启动、提交和回滚等操作。

  • Metadata Coordinator负责维护Kafka集群中各个Partition的元数据信息包括分区的leader和ISR等信息。

  • Admin Coordinator负责管理Kafka集群的各种配置信息包括topic的创建、删除和分区的增、删、改等操作。

我们这里要讲的就是其中的组协调器Group CoordinatorGroup Coordinator是一个服务每个Broker在启动的时候都会启动一个该服务。Group Coordinator的作用是用来存储Group的相关Meta信息并将对应Partition的Offset信息记录到Kafka内置Topic(__consumer_offsets)中当我们建立一个组的时候都会选择一个Coordinator来操作与存储自己组内各Partition的Offset信息

三、Rebalance机制

1. Rebalance的作用

我们前面提到消费者组里的各个消费者会被做分配操作。那如果某一个消费者挂掉了怎么办呢这个消费者负责的那些分区岂不是没人订阅了

别担心Kafka提供了Rebalance机制。Rebalance机制可以动态地分配分区使得每个消费者负载均衡提高消费效率和可用性。一般来说Rebalance机制会在以下情况下发生

  • 消费者加入或退出消费者组当消费者加入或退出消费者组时协调器会触发Rebalance机制
  • 分区数目发生变化当Kafka的主题被扩容或缩容时会触发Rebalance机制重新分配分区。。
  • Kafka Broker发生变化当Kafka Broker发生变化时例如节点重启或宕机等会触发Rebalance机制

其实很好理解A 订阅 B那显然只有当A 或 B 的数量发生变动的时候才需要再次平衡

2. Rebalance的实现

我们已增添一个消费者为例说明下Rebalance发生的全过程

  1. 消费者加入/退出当一个消费者加入或退出消费者组时它会向Group Coordinator发送JOIN GROUP或LEAVE GROUP请求。

  2. 协调者选举如果Group Coordinator收到的是JOIN GROUP请求则会根据Group Leader选举机制选举一个Group LeaderGroup Leader的职责是进行rebalance操作分配partition给消费者。注意Group Leader是消费者组内的某个消费者和Group Coordinator不是一个东西

  3. 分组协商Group Leader选举完成后它会向其他消费者发送SYNC GROUP请求要求其他消费者加入rebalance操作。其他消费者加入后Group Leader会根据消费者的订阅信息计算出新的分配方案。分配方案会以ASSIGN PARTITIONS请求的形式发送给每个消费者。

  4. 重新分配partition每个消费者在收到ASSIGN PARTITIONS请求后会按照分配方案重新分配自己需要消费的partition然后完成rebalance操作。

  5. 继续消费重新分配partition后消费者会继续从分配的partition中消费数据。

借用网上的图来说明下情况你也可以把整个Rebalance分为两步JoinSync

  • Join阶段所有成员都向coordinator发送JoinGroup请求请求加入消费组最后由Group Coordinator来选出其中一个消费者作为LeaderLeader能知道组内所有消费者。
    在这里插入图片描述
  • Sync阶段leader开始分配消费方案一旦完成分配leader会将这个方案封装进SyncGroup请求中发给coordinator非leader也会发SyncGroup请求只是内容为空。coordinator接收到分配方案之后会把方案塞进SyncGroup的response中发给各个consumer
    在这里插入图片描述
    而至于分配方案具体是怎样的其实就是在上一小节已经说过的 分区分配策略

3. Rebalance的优劣

Kafka的rebalance主要是为了实现消费者的负载均衡。通过上面的学习相信大家也能总结出rebalance机制的优点就是增强容错性支持动态扩容

  • 增强容错性当某个消费者意外退出或宕机rebalance可以重新分配该消费者所消费的partition给其他消费者从而保障消费的连续性并减少对业务的影响。

  • 支持动态扩容在Kafka系统运行中如果需要增加消费者数量rebalance可以根据新的消费者加入重新分配partition确保消费者的负载均衡。

但凡事有利有弊rebalance最大的缺点就是延迟影响性rebalance操作会涉及到分区的重新分配会导致系统有一定的延迟。如果消费者数量很大rebalance操作会更加复杂且耗时长。在这个期间所有的消费者都无法执行消费可以说影响面还是非常广的。


四、减少Rebalance的发生

我们在生产中如非必要应该尽量避免Rebalance这会暂停运行中的消费过程。最好是提前就做好各种预防措施而不是依靠Kafka的Rebalance来处理。

我们在前面说到消费者 和 分区 的数量变化会导致Rebalance一般其实是由于消费者的变动导致的如果是意外的宕机我们无法防止但是我们可以调整“短暂掉线”及“消费能力不足”的消费者对他们更加“宽容”一点具体如下

每个 Consumer 实例都会定期地向 Coordinator 发送心跳请求表明它还存活着。如果某个 Consumer 实例不能及时地发送这些心跳请求Coordinator 就会认为该 Consumer 已经 “死” 了从而将其从 Group 中移除然后开启新一轮 Rebalance。这个时间可以通过Consumer 端的参数 session.timeout.ms进行配置。默认值是 45 秒

在这里插入图片描述

Consumer 端还有一个参数用于控制 Consumer 实际消费能力对 Rebalance 的影响即 max.poll.interval.ms 参数。它限定了 Consumer 端应用程序两次调用 poll 方法的最大时间间隔。它的默认值是 5 分钟表示你的 Consumer 程序如果在 5 分钟之内无法消费完 poll 方法返回的消息那么 Consumer 会主动发起 “离开组” 的请求Coordinator 也会开启新一轮 Rebalance

在这里插入图片描述
一般来说为了预防Rebalance我们可以调大上面两个参数同时加快心跳频率也就是调小heartbeat.interval.ms

在这里插入图片描述

总结

本期我们讲了Kafka消费端的成组设置也了解了组内的分配规则以及消费者发生变动后会导致的Rebalance机制最后介绍了减少Rebalance发生的一些参数调整。希望大家能有所收获下次我们将继续深入讲解Kafka的其他原理如果你对此有兴趣可以直接订阅本 kafka 专栏

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6