连载中 14/20

Kafka 分区与消费者组:Rebalance 风暴

2026-08-06 · 2850 阅读 · 0 评论 · 0 赞

一次「扩容引发的停摆」

老王给 Kafka 消费组加了一台机器,预期消费能力翻倍,结果监控上消费 TPS 直接归零了一分多钟,还冒出一堆重复消费。这就是Rebalance(再均衡):分区在组内成员之间重新分配的过程。这一篇讲清楚它何时发生、为什么慢、怎么治。

分区怎么分:分配策略的演进

Rebalance 的核心动作是把 partition 分给组里的 consumer。策略有几代:

  • RangeAssignor:按 Topic 逐个切分分配,缺点是排前面的消费者总多拿一点,负载略偏;
  • RoundRobinAssignor:轮询均分,比 Range 均衡,但 Rebalance 时几乎全组分区的归属都会变动;
  • StickyAssignor:在均衡的前提下,尽量保留每个消费者原有的分区——减少无谓的分区搬家;
  • CooperativeStickyAssignor(2.4+):增量协作式 Rebalance,只收回真正需要迁移的分区,其余消费者边干活边迁移,把全组停摆变成局部停摆。新版本默认首选。

何时触发:四类导火索

  • 组内成员增减:扩容、缩容、消费者崩溃或优雅退出;
  • 心跳超时(session.timeout.ms 内没收到心跳):消费者被判定死亡;
  • 两次 poll 间隔超时(max.poll.interval.ms):一批消息处理太久,被认为卡死;
  • 订阅变化:Topic 数量或正则订阅匹配结果变了。

生产的 Rebalance 风暴,八成是后两类「假死」触发的:消费者活得好好的,只是 GC 停顿太久没发心跳,或者单批数据处理超过了 max.poll.interval.ms——Kafka 误判它死了,于是全组重分,重分期间整组停摆(Eager 协议),重分完位点回退又开始重复消费。一个故障触发一轮 Rebalance,Rebalance 又引发停摆和重复,雪球就这么滚起来了。

治风三招

第一招:参数配比。心跳要快于超时的一半:session.timeout.ms=45s 时,heartbeat.interval.ms 设 3s,留足误判余量。max.poll.interval.ms 要大于最慢一批的处理时间,同时调小 max.poll.records(默认 500),让每批处理时间可控——处理能力不够靠加消费者,而不是靠一次拉一大堆。

第二招:静态成员。给每个消费者配置 group.instance.id(静态成员标识)。重启不换 ID,Broker 认出它是老朋友,常规发版重启不再触发 Rebalance——这个参数治好了半个行业的停摆。

第三招:换协作协议。启用 CooperativeStickyAssignor,把全组 STW 缩成受影响分区的局部暂停。升级要整组版本一致,灰度时注意。

offset 的管理与提交

消费进度(offset)记在 Broker 端的内部主题 __consumer_offsets 里。提交 API 两种:commitSync(同步,可靠但阻塞)与 commitAsync(异步,快但可能丢提交)。工程惯例是两者混用:平时异步提交保持吞吐,消费循环结束或关闭前同步提交一次保底。再加一条第 6 篇的铁律:先处理完业务再提交,宁可重复不可丢失。Rebalance 监听器(ConsumerRebalanceListener)里记得在分区被收回前做最后一次同步提交,能少一批重复。

排查清单

症状排查方向
频繁 Rebalance消费者 GC 日志、心跳线程、max.poll.interval 是否被慢 SQL/慢 RPC 拖爆
Rebalance 后大量重复提交间隔太长,位点回退窗口大;检查监听器是否补提交
发版必停摆没用静态成员或滚动发版顺序不对
部分分区长期无消费消费者数多于分区数,多出来的在空转

小结

Rebalance 本身不是故障,是必要机制;故障的是被误判触发的频繁全量 Rebalance。三招治风:参数配比防误判、静态成员防发版、协作协议降爆炸半径。配比口诀:心跳不过会话半,批处理不过间隔半。

Kafka 两篇完结。下一篇回到 RocketMQ:NameServer 的无状态路由、主从与 Dledger 的自动切换——老王的生产集群到底怎么搭。

503

10 年全栈工程师 · 503咖啡馆主理人

#消息队列#Kafka#Rebalance#消费者组#分区分配

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞