当前位置: 首页 > news >正文

RocketMQ和Kafka一样有重平衡的问题吗?

文章目录

  • 1.Kafka的重平衡机制
  • 2.Kafka重平衡优化
  • 3.RocketMq的重平衡问题
  • 4.Kafka VS RocketMq
  • 5.面试话术

1.Kafka的重平衡机制

在集群模式下,一定会涉及到消费者节点数或Broker分区数的变化,如:

  1. 消费者加入/离开组(如扩容、宕机)
  2. 订阅 Topic 分区变化(如分区数增加)
  3. 心跳超时(默认 session.timeout.ms=45s)等

Kafka 的重平衡机制是指在消费者组中新增或删除消费者时,Kafka 集群会重新分配主题分区给各个消费者,以保证每个消费者消费的分区数量尽可能均衡。

重平衡机制的目的是实现消费者的负载均衡和高可用性,以确保每个消费者都能够按照预期的方式消费到消息

虽然kafka没有像RocketMq那样有NameServer的注册中心去维护Broker、消费者、发送者之间的联系,但是它可以通过组织协调器 (Group Coordinator) 管理消费者组的 Broker 节点。

如果它崩渍或者发生故障Kafka 需要重新选举新的 Group Coordinator ,并进行重平衡。

而且当消费者组中的 Leader 消费者崩溃或退出。Kafka 需要选举新的 Leader,重新进行重平衡
一旦触发Rebalance,就会执行以下流程:

  • 1.暂停消费:在重平衡开始之前,Kafka 会暂停所有消费者的拉取操作,以确保不会出现重平衡期间的消息丢失或重复消费。
  • 2.计算分区分配方案:Kafka 集群会根据当前消费者组的消费者数量和主题分区数量,计算出每个消费者应该分配的分区列表,以实现分区的负载均衡。
  • 3.通知消费者:一旦分区分配方案确定,Kafka 集群会将分配方案发送给每个消费者,告诉它们需要消费的分区列表,并请求它们重新加入消费者组。
  • 4.重新分配分区:在消费者重新加入消费者组后,Kafka 集群会将分区分配方案应用到实际的分区分配中,重新分配主题分区给各个消费者
  • 5.恢复消费: 最后,Kafka 会恢复所有消费者的拉取操作,允许它们消费分配给自己的分

这个很像我们JVM FullGC之后的STW,所以我们尽可能的要避免重平衡时的STW

kafka的设计是遵循分布式原则CAP里的CP(强一致性),通过 组协调器(Group Coordinator) 管理分区分配,确保每个分区仅被一个消费者消费,依赖心跳机制,响应快(但频繁触发可能导致性能抖动)

2.Kafka重平衡优化

默认情况下,消费者离开后会导致重平衡。但如果开启静态成员,Kafka 不会立即移除该消费者,而是等待一段时间 ( group.instance.id )。这样,如果消费者重启,Kafka 仍然保持它的分区分配,不触发重平衡。

还有就是,Kafka 提供了多种分区分配策略,选择合适的策略可以减少重平衡的影响:

  • RangeAssignor (默认): 基于 range 分配,可能导致不均衡
    • 按 Topic 分区排序,消费者按字典序排序,平均分配余数优先给前序消费者
例如:Topic "orders"5个分区
● 分区排序:P0, P1, P2, P3, P4
消费者名称:["consumer-2", "consumer-1", "consumer-3"]
按字典序排序后:["consumer-1", "consumer-2", "consumer-3"]
按照:先平均分配,余数分配给排序靠前的消费者的逻辑
● 1. 计算基础分配数 = 分区总数 / 消费者数量
● 2. 计算余数 = 分区总数 % 消费者数量
● 3."余数"个消费者多分配1个分区
按照上面的步骤:
● 5/3=15%3=2
前两个消费多分配1个分区,即:
consumer-1:P0,P1
consumer-2:P2,P3
consumer-3:P4
  • RoundRobinAssignor:轮询分配,适用于均匀分布的消费者
    • 所有 Topic 的分区按哈希排序,消费者按字典序排序,轮询分配
分区排序 = [P0, P1, P2, P3, P4]
消费者排序 = [C1, C2, C3]# 轮询顺序:
C1 → P0
C2 → P1
C3 → P2
C1 → P3
C2 → P4
  • StickyAssignor: 优先保持之前的分区分配,减少重平衡。
    • 优先保留原有分配结果,仅调整变动部分(减少重平衡时分区迁移)
    • 假如刚开始是:3 消费者 → 5 分区 ,分配策略同 RoundRobin
分区排序 = [P0, P1, P2, P3, P4]
消费者排序 = [C1, C2, C3]# 轮询顺序:
C1 → P0
C2 → P1
C3 → P2
C1 → P3
C2 → P4

新增一个消费者后 C4 时:

  • 仅从 C1、C2 各迁移 1 个分区给 C4
  • 最小化迁移:C1 保留 P0,C2 保留 P1,C3 保留 P2,C4 获得 P3、P4
分区排序 = [P0, P1, P2, P3, P4]
消费者排序 = [C1, C2, C3,C4]C1 → P0
C2 → P1
C3 → P2
C4 → P3
C4 → P4
  • CooperativeStickyAssignor: 渐进式重平衡,不会影响所有消费者,只影响变更的部分
    • 该分配策略只在kafka2.4+生效
    • 初始分配阶段:
      • 消费者组启动时,所有消费者参与分配
      • 使用StickyAssignor算法进行初始分配
      • 每个消费者获得分区分配
      • 开始消费

在具体实践中可以通过:

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "order-group");
props.put("partition.assignment.strategy", "org.apache.kafka.clients.consumer.RoundRobinAssignor"); // 指定策略
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);

同时在kafka最新发布的4.0版本中(2025-03-19),提出了下一代消费者重平衡协议,一方面将分区分配逻辑从客户端移到了服务端,简化客户端更加简单,而且这样服务端也能从全局视角更好的处理重平衡。

另外有个比较大的改进,就是允许消费者独立于其他成员进行重平衡了,这就意味着当一个消费者发生变化时,不再需要暂停整个组,其他消费者可以继续正常工作,提高了系统的可靠性和扩展性。

3.RocketMq的重平衡问题

广播模式下,每个消费者都会消费所有消息,不存在重平衡问题。 但是如果实在默认的集群模式下,消费者在一个消费组中,多个消费者会均摊消费,这时候就涉及重平衡的问题。

RocketMQ 的重平衡机制触发条件:

  • 消费者加入/退出组。
  • Topic 的队列数变化。
  • 定时触发:默认每 20 秒检查一次(通过 RebalanceService 线程)。
    • 核心特点:
      • 无全局停顿:消费者通过 本地计算 + 异步拉取 实现渐进式重平衡。
      • 弱一致性:消费者定期从 NameServer 获取元数据,本地计算分配策略(如均分、环形)。
      • 延迟容忍:若消费者宕机,最多需 20 秒触发重平衡(相比 Kafka 的实时响应,延迟更高)。

通过其特点也能看出和Kafka不同的是,RocketMQ他只有个定时重平衡的机制,他有一个重平衡检查线程,会自动的每 20s 进行一次重平衡检查,如果发现有消费者新增或离开时,会触发重新分配队列。

重平衡检查机制核心代码:

    @Overridepublic void run() {log.info(this.getServiceName() + " service started");long realWaitInterval = waitInterval;while (!this.isStopped()) {this.waitForRunning(realWaitInterval);long interval = System.currentTimeMillis() - lastRebalanceTimestamp;if (interval < minInterval) {realWaitInterval = minInterval - interval;} else {boolean balanced = this.mqClientFactory.doRebalance();realWaitInterval = balanced ? waitInterval : minInterval;lastRebalanceTimestamp = System.currentTimeMillis();}}log.info(this.getServiceName() + " service end");}

正是因为RocketMQ 定时进行重平衡的,而不是像 Kafka 依赖心跳机制做实时重平衡a,那么就会出现如果一个消费者宕机,最多需要 20s 才能触发重平衡,导致这段时间内消息堆积在已宕机的消费者上,影响吞吐。不过定时也有个好处就是避免很多网络抖动,或者频繁增加、退出消费者等导致的频繁的重平衡。

但是相比于Kafka,RocketMQ的重平衡机制最大的好处是STW的影响很小

由于 RocketMQ 的消费者是通过 异步拉取然后再放到本地队列处理消息的,即使重平衡发生,每个消费者仍然可以继续消费它当前的队列中的消息,只要重平衡的时间足够短,就可以完全消除STW的发生,因为这段时间本地队列中消息还是在正常处理的。一旦重平衡好了,拉取的时候拉取新的队列的消息就行了。

还有就是RocketMQ 在消费者重平衡时是通过默认就是通过局部调整来完成的。当消费者变化时,只有受影响的消费者会重新分配消息队列,其他消费者不受影响。(类似kafka的渐进式重平衡,但是RocketMQ默认就是这样的)

4.Kafka VS RocketMq

在这里插入图片描述

Kafka 配置优化示例:

props.put("partition.assignment.strategy", "org.apache.kafka.clients.consumer.RoundRobinAssignor");
props.put("session.timeout.ms", "60000"); // 增大超时时间,减少误触发
props.put("enable.auto.commit", "false"); // 手动提交 Offset,避免重平衡时重复消费

RocketMQ 配置优化示例:

consumer.setAllocateMessageQueueStrategy(new AllocateMessageQueueAveragely());
consumer.setPullBatchSize(32); // 减少拉取频率,降低重平衡压力

5.面试话术

重平衡带来的最大问题就是STW问题,一旦触发重平衡,就会暂停消费,影响吞吐。像Kafka通过协调者监听消费者心跳,能够快速感知消费者的数量变化,进而进行重平衡机制,kafka默认的分区分配策略是基于范围分配,且默认情况下消费者离开后就会触发重平衡,但是如果开启静态成员,那么kafka不会立刻移除该消费者,而是等一段时间,那么其他消费者在就可以正常消费,所以推荐使用StickyAssignor或者渐进式重平衡,不会影响所有消费者而是只影响变更的部分。而RocketMq首先在广播模式下不会有重平衡问题,因为所有的消费者均会消费,但是默认的集群模式下,当消费者组数量发生变化以及Topic的队列数发生变化也会有重平衡问题,rocketMq的消息拉取线程拉到的消息不是直接消费,而是放在ProcessQueue里等待消费者线程去消费,并且有一个定时重平衡线程每20s去检查一次,所以会有20s的缓冲,并结合ProcessQueue,可以很大程度上避免重平衡带来的STW,但是会导致RocketMq反应稍慢,还有就是RocketMq的消费者平衡默认就是通过调整局部来完成的,只有受到影响的消费者会重新分配队列,其他消费者并不受影响,而Kafka需要手动开启,两个方案各有优缺点,像kafka适合实时性要求极高的场景,而RocketMQ适合稳定性要求高的场景。

http://www.dtcms.com/a/318254.html

相关文章:

  • 机器学习——朴素贝叶斯
  • Java面试题和答案大全
  • Web 端 AI 图像生成技术的应用与创新:虚拟背景与创意图像合成
  • Session 和 JWT(JSON Web Token)
  • [AI]从零开始的SDXL LORA训练教程
  • 机器视觉的智能手表贴合应用
  • Android 之 ViewBinding 实现更安全、高效的视图绑定
  • envFrom 是一个 列表类型字段bug
  • W3D引擎游戏开发----从入门到精通【22】
  • 《聚氨酯垫性能优化在超薄晶圆研磨中对 TTV 的保障技术》
  • 小实验--震动点灯
  • 昇思+昇腾开发板+DeepSeek模型推理和性能优化
  • Python实现信号小波分解与重构
  • 【CUDA】C2 矩阵计算
  • 大数据之Flume
  • 01--CPP入门
  • Unity里的对象旋转数值跳转问题的原理与解决方案
  • GaussDB 数据库架构师修炼(六)-2 集群工具管理-重建备库
  • 17.10 智谱AI GLM 篇:ChatGLM3-6B 快速上手
  • 【教程】C++编译官方CEF3
  • ORA-10458: standby database requires recovery
  • C++ Eigen最小二乘拟合三维直线
  • KMP-next数组详解
  • sigaction结构体详解
  • 推荐一款优质的开源博客与内容管理系统
  • 集团敏捷组织转型项目研讨材料(105页PPT)精品
  • Mac安装WebStorm for Mac v2025.1.1
  • PDF注释的加载和保存的实现
  • Enhancing Long Video Question Answering with Scene-Localized Frame Grouping
  • python中的推导式