Kafka实战二之消费组频繁Rebalance排查

内容分享4小时前发布
1 2 0

问题描述

我们开发了一个广告归因项目,需要每隔3分钟从第三方平台拉取创意数据并保存到ClickHouse。第三方平台包括 巨量,广点通,华为,OPPO,VIVO,百度等,监控kafka消费信息,一直不消费消息,查询服务器,且没有日志打印。那是什么缘由导致消息无法正常消费呢?

Kafka实战二之消费组频繁Rebalance排查

Kafka 核心配置

下面是Kafka 消费者的配置信息

spring:
	  kafka:
    	bootstrap-servers: 127.0.0.1:50001
    	consumer:
      group-id: launch-mq-prod
      auto-offset-reset: latest
      # 是否在消费消息后将 offset 同步到 Broker,当 Consumer 失败后就能从 Broker 获取最新的 offset
      enable-auto-commit: false
      ## 当 auto.commit.enable=true 时,自动提交 Offset 的时间间隔,提议设置至少1000
      auto-commit-interval: 2000
      max-poll-records: 200
      poll-timeout: 1000
      heartbeat-interval: 3000
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      properties:
        # 使用 Kafka 消费分组机制时,消费者超时时间。当 Broker 在该时间内没有收到消费者的心跳时,认为该消费者故障失败,Broker 发起重新 Rebalance 过程。目前该值的配置必须在 Broker 配置group.min.session.timeout.ms=6000和group.max.session.timeout.ms=300000 之间
        session.timeout.ms: 60000
        # 使用 Kafka 消费分组机制时,消费者发送心跳的间隔。这个值必须小于 session.timeout.ms,一般小于它的三分之一
        heartbeat.interval.ms: 3000
        # 使用 Kafka 消费分组机制时,再次调用 poll 允许的最大间隔。如果在该时间内没有再次调用 poll,则认为该消费者已经失败,Broker 会重新发起 Rebalance 把分配给它的 partition 分配给其他消费者
        max.poll.interval.ms: 300000
        fetch.max.wait.ms: 1000
        # 该属性指定了消费者从服务器消费数据的最小字节数
        fetch.min.bytes: 2048
        request.timeout.ms: 600000

Kafka消费者超时配置

以下是关于Kafka消费者超时配置的一些常见选项:

1、session.timeout.ms:该配置定义了消费者与Kafka集群之间的会话超时时间。如果消费者在此超时时间内未发送心跳到服务器,服务器将其标记为离线并触发重新平衡操作。默认值为10秒。

2、max.poll.interval.ms:此配置定义了消费者处理单个调用poll()方法的最大时间。如果在此时间内未调用poll(),则Kafka将认为消费者已死亡,并将其标记为离线。这个配置可用于控制消费者处理消息的速度。默认值为5分钟。

3、request.timeout.ms:该配置定义了消费者向服务器发出请求的超时时间。如果在此时间内未收到服务器的响应,消费者将认为请求失败并尝试重新发送请求。默认值为30秒。

4、heartbeat.interval.ms:表明 consumer 每次向 broker 发送心跳的时间间隔。heartbeat.interval.ms = 3000 表明 consumer 每 3 秒向 broker 发送一次心跳。一般来说,session.timeout.ms 的值是 heartbeat.interval.ms 值的 3 倍以上。

这些配置选项可以在消费者的配置文件或代码中设置。请注意,超时时间的设置应该根据具体情况进行调整,以确保消费者能够适当地处理消息并与Kafka集群保持连接。

问题排查

Kafka实战二之消费组频繁Rebalance排查

通过查看Kafka监控信息,从图中可以发现,消费分组发生了Rebalance。那么什么是Rebalance呢?Rebalance会导致什么问题呢?

Rebalance 概念

就 Kafka 消费端而言,有一个难以避免的问题就是消费者的重平衡即 Rebalance。Rebalance是让一个消费组的所有消费者就如何消费订阅 topic 的所有分区达成共识的过程,在 Rebalance 过程中,所有 Consumer 实例都会停止消费,等待 Rebalance 的完成。由于要停止消费等待重平衡完成,因此 Rebalance 会严重影响消费端的 TPS,是应当尽量避免的。

结论

由于在消费消息时,我们要查询ClickHouse,大量的查询请求导致ClickHouse服务器CPU飙高,查询时间过长,我们配置的session.timeout.ms: 60000,max.poll.interval.ms: 300000。批量消息未能在300S内消费完毕,导致Kafka频繁发生Rebalance,消息无法正常消费。

在Kafka0.10.1 之前:

  • 检查整个消费者死亡和检查消费者处理线程,使用的同一个线程,如果设置的max.poll.interval.ms大于session.timeout.ms,遇到一个处理时间过长的消息,会由于线程忙于处理消息,而无法发送心跳,导致Kafka认为该消费则已完全死亡,进而进行Rebalance
  • 所以推荐设置:heartbeat.inerval.ms < max.poll.interval.ms < session.timeout.ms

在Kafka0.10.1之后:

  • session.timeout.ms 和 max.poll.interval.ms 解耦了,拆成了两个线程,不用再担心它们之间的依赖关系
  • 推荐设置:heartbeat.interval.ms < session.timeout.ms

Consumer Group 状态说明

消费者组列表页中 Consumer Group 的状态主要有 Dead、Empty、PreparingRebalance、AwaitingSync、Stable 几种,其中最常见的是 Empty、Stable 和 Dead 三种状态。Consumer Group 中的状态机转换如下图所示:

Kafka实战二之消费组频繁Rebalance排查

Dead:消费者组内无成员并且 Metadata 已经被移除。

Empty:消费分组内当前没有任何成员。如果组内所有 offset 都已过期,则会变为 Dead 状态。一般新创建的 Group 默认为 Empty 状态。 开源 Kafka 0.10.x 版本规定,当消费分组内没有任何成员且状态持续超过7天,此消费分组将会被自动删除。

Stable:消费分组中各个消费者已经加入,处于稳定状态。

Rebalance 发生缘由

根据 Consumer Group 的状态机可知,当 Consumer Group 为 Empty、AwaitSync 或 Stable 状态时,Group 可能会进行 Rebalance。以下情况可能会发生 Rebalance:

  • 一个消费者订阅了 Topic。
  • 消费者被关闭。
  • 某个 Consumer 被 Group Coordinator(协调器)认为是 Dead 状态时。 如果某个Consumer 在session.timeout.ms时间内没有给 Group Coordinator 发心跳,则该 Consumer 将被认为是 Dead 状态,并且发起 Rebalance。
  • 分区数增加。
  • 订阅了不存在的 Topic。 如果您订阅了一个还未创建的 Topic,那么当这个 Topic 创建后会发生 Rebalance;同理,如果一个已经被订阅的 Topic 被删除,也会发生 Rebalance。
  • 应用崩溃。

Rebalance 过程分析

以0.10版本Kafka 的机制为例,Rebalance 过程分析如下:

1. 任何一个 Consumer 想要加入到一个 Consumer Group 中时,会发送一个 JoinGroup 的请求给 Group Coordinator。第一个加入 Group 的 Consumer 会变成 Group Leader。

2. Leader 会从 Group Coordinator 处收到这个 Group 中所有 Consumer 列表,并且负责给 Group 中的 Consumer 分配 partition。分区的分配可以通过 PartitionAssignor 接口来实现。

3. 分配完成后,Leader 会把分配结果发给 Group Coordinator,Coordinator 会把结果发送给所有的 Consumer。 因此,每个 Consumer 只能查看到自己被分配的 partition,Leader 是唯一能够拿到Consumer Group 中的 Consumer 以及其分区情况的节点的 Consumer。

上述过程会在每次 Rebalance 发生时执行一次。

© 版权声明

相关文章

2 条评论

  • 头像
    攒钱给闺蜜点8个男模跳蹦擦擦 投稿者

    收藏了,感谢分享

    无记录
    回复
  • 头像
    中医技术传承者 读者

    向你学习👍

    无记录
    回复