下面给你详细讲解 Kafka 3.x 的 Incremental Cooperative Rebalancing(增量协作式重平衡) ,这是 Kafka 在高吞吐实时系统中非常重要的优化之一,能显著减少停顿时间和抖动。
内容会分 5 部分讲:
- 它解决了什么问题
- 与旧的 Rebalance 方式对比
- 增量重平衡的核心机制
- 实际案例演示(非常重要)
- 如何启用以及注意点
1. 传统 Rebalance 的痛点是什么?(为什么要改它?)
Kafka 2.x 以前默认是
EAGER
(急切式) rebalance:
重平衡触发时:
- 所有消费者 必须先全部放弃分区
- 再统一重新分配分区
导致问题:
| 问题 | 影响 |
|---|---|
| 消费完全中断(全停顿) | 业务延迟激增 |
| 频繁 rebalance 时系统抖动严重 | 稳定性下降 |
| 大组规模下 rebalance 时间更长 | 甚至会雪崩 |
这种停顿往往持续 数秒甚至十几秒。
特别是如果某个消费者执行较慢 poll/commit 操作,整个 group 就一直处于阻塞状态。
Kafka 在高吞吐业务(订单、日志流、计费、推荐系统等)中尤其容易遇到这个问题。
2. Kafka 3.x 的新增机制:Incremental Cooperative Rebalancing
Kafka 新版本提供了 合作式(Cooperative) rebalance,它的核心理念是:
让消费者只撤销必要的分区,而不需要全集体暂停,从而做到“边 rebalance 边消费”。
也叫:
- Incremental Rebalance
- Cooperative Rebalance
- 增量重平衡
默认的 partition assignor 为:
- CooperativeStickyAssignor
3. 增量重平衡的核心机制(重点)
增量重平衡的本质:
⚙️ 原理核心
在 rebalance 过程中:
- 消费者不再一次性丢弃所有分区
- 而是执行 两阶段重平衡
阶段 1:撤销部分分区(Partial Revoke)
消费者收到 rebalance 开始的通知时:
- 只释放那些不再属于自己的分区
- 保留仍可以继续消费的分区,不会停顿
这意味着消费仍然可以在过程中继续推进。
阶段 2:分配新分区(Assign New Partitions)
在所有消费者释放完必要的分区后:
- 再进行一次轻量级 rebalance
- 将“被释放的分区”重新分配
因为此时:
- 未必所有消费者都会撤销分区
- 分配集很小
- 因此重平衡影响范围显著缩小
最终效果:
大部分情况下,只有非常少量的分区被迁移,消费者不会完全停顿。
4. 实际案例演示(非常重要,能让你一下理解)
假设:
- Topic 有 6 个分区
- Consumer Group 有 3 个消费者:C1, C2, C3
初始分配:
- C1 → p0, p1
- C2 → p2, p3
- C3 → p4, p5
🆕
现在新加入 C4
✔️ 旧的 EAGER Rebalance:
-
所有消费者全部放弃(撤销 p0~p5)
-
整个组进入停顿状态
-
重新分配 6 个分区给 4 个消费者
-
全组恢复消费
停顿较长,很痛苦
✔️ Incremental Cooperative Rebalance:两次小操作即可
🟦第一次:局部释放
新方案下,第一次分配时,会要求:
- C1、C2、C3 只释放部分分区
可能仅释放:
- C1:p1
- C2:p3
- C3:p5
这些分区“让出来”给 C4。
但关键点:
- C1、C2、C3 还继续消费剩下的 p0、p2、p4(不暂停)
- C4 暂时什么分区都没有(等第二次)
🟧第二次:最终分配
在第二阶段,Kafka 将被释放的 p1、p3、p5 分配给 C4,完成整个 rebalance。
最终效果:
- 没有全局停顿
- 只有必要分区被迁移
- rebalance 影响范围变得很小
5. 如何启用增量重平衡(非常简单)
消费者客户端配置:
partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor
或新版写法:
partition.assignment.strategy=cooperative-sticky
消费者代码(Java):
props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,
Collections.singletonList(CooperativeStickyAssignor.class.getName()));
6. 注意事项
⭐ 必须让所有 consumer 都使用 CooperativeStickyAssignor
否则会导致不可预期的 rebalance 行为。
⭐ 重写 onPartitionsAssigned 与 onPartitionsRevoked
增量模式下:
- revoked 的分区是不完整的(只部分)
- assigned 的分区也可能是增量的
→ 必须支持“增量处理”,不能假设是全量更新。
⭐ 提升大消费者组的稳定性
如果 group 有几十上百个消费者,效果非常显著。
🏁总结一句话
Kafka 3.x 的增量重平衡让消费者在 rebalance 时不再全体停顿,只撤销必要的分区,大幅降低业务延迟和系统抖动,是企业生产环境强烈推荐启用的模式。