kafka rebalance(再均衡)导致的消息积压分析

起因:

某天,项目组收到大量的kafka消息积压告警。查看了kafka日志后,发现 kafka不断地 rebalance(再均衡)。

Rebalance (再均衡):

分区的所有权从一个消费者转移到另一个消费者,这样的行为被称为Rebalance (再均衡).
在再均衡期间,消费者无法消费消息,造成整个群组一小段时间的不可用。

Rebalance 的触发条件:

  • 当 Consumer Group 组成员数量发生变化
    (1)新成员加入
    (2)组成员主动离开

    (3)组成员崩溃

    • 消费者心跳超时,导致 rebalance。
    • 消费者处理时间过长,导致 rebalance。
  • 当订阅主题数量发生变化

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

日志:

[2023-12-11 xx:xx:xx] INFO [GroupCoordinator 1]: Member consumer-anonymous. in group anonymous. has failed, removing it from the group (kafka.coordinator.group.GroupCoordinator)
[2023-12-11 xx:xx:xx] INFO [GroupCoordinator 1]: Preparing to rebalance group anonymous. in state PreparingRebalance with old generation 1 (__consumer_offsets-5) (reason: removing member consumer-anonymous. on heartbeat expiration) (kafka.coordinator.group.GroupCoordinator)
[2023-12-11 xx:xx:xx] INFO [GroupCoordinator 1]: Group anonymous. with generation 2 is now empty (__consumer_offsets-5) (kafka.coordinator.group.GroupCoordinator)
[2023-12-11 xx:xx:xx] WARN Attempting to send response via channel for which there is no open connection, connection id :9092 (kafka.network.Processor)

原因:

kafka消费消息后,如果业务逻辑处理时间过长,会导致消费线程与 Coordinator(协调器) 的 heartbeat (心跳) 超时,Coordinator 判断 Consumer 已经宕机,就将 Consumer 从消费组中剔除,并触发了 Rebalance 机制 。

解决:

优先解决生产问题:先调整消费者的参数,避免频繁 Rebalance。

如果想从根本上解决,还需要优化消费逻辑,提高性能,快速消费完,避免超时。

在创建消费者 KafkaConsumer 时,需要指定各个参数。这些参数在Kafka 的 ConsumerConfig 类上都有常量定义。

Properties properties = new Properties();
properties.put("group.id", groupId);
properties.put("session.timeout.ms",  time);
properties.put("heartbeat.interval.ms",  interval);
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);

可以优化的参数如下:

session.timeout.ms : 心跳超时时间
heartbeat.interval.ms  : 心跳时间间隔
max.poll.interval.ms  : 每次消费的处理时间
max.poll.records  : 每次消费的消息数
  • session.timeout.ms: 心跳超时时间,默认 10s。当心跳超时时间超过 session.timeout.ms ,会认为 Consumer 已退出 ,将 Consumer 从消费组中剔除,触发 Rebalance 机制。可以适当调大 session.timeout.ms,避免频繁 Rebalance 。

  • heartbeat.interval.ms : 这个是心跳时间间隔,默认值是:3s。 该值必须小于 session.timeout.ms,否则会超时。

  • max.poll.interval.ms :如果消费端在该间隔内没有发起 poll 操作,该消费者将被剔除,触发重平衡,将该消费者分配的队列分配给其他消费者。默认为 5 分钟。

  • max.poll.records: 每次消费的时候,获取多少条消息。默认值为 500。
    获取的消息条数越多,需要处理的时间越长。所以每次拉取的消息数不能太多,需要保证在 max.poll.interval.ms 设置的时间内能消费完,否则会发生 rebalance。可以适当调小 max.poll.records,避免频繁 Rebalance 。

参考资料:

https://blog.csdn.net/riemann_/article/details/122484531

https://blog.csdn.net/penriver/article/details/121556161

posted on 2023-12-11 23:08  乐之者v  阅读(373)  评论(0编辑  收藏  举报

导航