一文读懂kafka重平衡

什么是 kafka 重平衡?

重平衡也叫 Rebalance,本质上是一种协议,规定了一个消费组下的所有消费者如何达成一致,来分配订阅 Topic 的每个分区,比如某个消费组下有10个消费者实例,它订阅了一个具有50个分区的 Topic,正常情况下,Kafka 平均会为每个消费者分配5个分区,这个分配的过程就叫 Rebalance。

为什么 kafka 会发生重平衡?

消费组发生 Rebalance 有三种情况:

  • 消费者成员数发生变更

有消费者实例加入消费组或者离开消费组,或者有消费者实例崩溃被"踢出"消费组,从而发生 Rebalance。

  • 订阅主题数量发生变更

消费组一开始只是订阅 Topic A 和 Topic B,某次上线消费组订阅 Topic C,消费组发生 Rebalance。

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

当 Topic 分区数增加时,就会触发订阅该主题的所有消费组发生 Rebalance。

kafka 重平衡有什么影响?

Rebalance 过程中,消费者组的消费者都会停止消费(Stop-The-World),直到 Rebalance 完成,这会导致,

  • 消费暂停

整个消费者组在重平衡期间无法处理消息,很容易影响业务正常运行。

  • 重复消费

消费者在重平衡前未完成提交的偏移量导致消息被重复处理,一旦业务没有做好幂等处理,容易产生脏数据。

如何避免 kafka 发生重平衡?

  • 要避免 Rebalance,还是要从 Rebalance 产生的原因入手,消费者组成员数量发生变化、订阅主题数量发生变化、订阅主题的分区数发生变化都会使得消费组发生 Rebalance。

  • 其中订阅主题数量发生变化、订阅主题的分区数发生变化不可避免。消费者组成员数量增加主要是配置了相同的group.id 程序会添加到这个消费者组中,发生 Rebalance,这个不是我们需要考虑的。

  • 消费者组成员减少才是我们需要重点研究的,那什么情况会出现消费者成员减少?

消费者心跳超时导致

消费者因为未能及时发送心跳,导致消费者被"踢出"消费组而引发 Rebalance。

消费者心跳与 session.timeout.msheartbeat.interval.ms 两个参数有关。

一般来说 session.timeout.ms >= 3 * heartbeat.interval.ms。这么设置源自 Kafka 官方推荐和实际运维经验。

消费者消费时间过长导致

如果在最大间隔时间内未将消息处理完毕,触发消费组 Rebalance。消费者消息处理速度与 max.poll.interval.ms、max.poll.records 两个参数有关。

  • max.poll.interval.ms:消费者两次 poll 最大间隔时间。

  • max.poll.records:消费者单次 poll 最大消息数。

两个参数简单设置:max.poll.interval.ms >= 单个消息处理时间 * max.poll.records。

笔者就遇到过一个业务场景,消费者消费消息需要将消息处理之后写入到 MySQL,某天 MySQL 发生慢查导致消费者程序消费时长突增,消费组发生 Rebalance。总之,一定要给业务处理逻辑留下充足的时间来避免 Rebalance。

经验之谈,一旦发生 Rebalance 不要着急,分析整个消费者链路,逐个依赖排查,遇到问题,解决问题。

相关推荐
予枫的编程笔记3 小时前
【Kafka进阶篇】Spring Boot Kafka客户端踩坑记:自定义序列化器+ContainerFactory调优指南
java·spring boot·kafka·java21·并发消费·kafka客户端·自定义序列化器
予枫的编程笔记3 小时前
【Kafka进阶篇】Canal+Kafka+ES实战:内容平台数据同步难题,这样解最优雅
redis·mysql·elasticsearch·kafka·canal·数据同步·异步解耦
予枫的编程笔记1 天前
【Kafka进阶篇】Kafka消息重复消费?Exactly-Once语义落地指南,PID+事务消息吃透
人工智能·kafka·消息队列·exactly-once·分布式消息·kafka幂等性·kafka事务消息
星辰_mya1 天前
Kafka 的 KRaft 模式
分布式·kafka
yangyanping201081 天前
消息队列之消费者如何获取消息
分布式·架构·kafka
星辰_mya1 天前
Kafka Producer 发送慢 → TPS 骤降 90%
java·数据库·kafka
lucky67071 天前
Laravel7.X十大核心特性解析
spring boot·kafka·linq
星辰_mya1 天前
Kafka之Broker 磁盘写满 → 整个集群只读
分布式·kafka