RocketMQ Rebalance机制剖析

基础概念

Rebalance(再均衡)指的是:将一个 topic 下的多个队列(或称之为分区),在同一个消费者组(consumer group)下的多个消费者实例(consumer)之间进行重新分配。

Rebalance 本意是为了提升消息的「并行处理」能力。

触发时机

Consumer rebalance 的触发时机:topic 的 queue 数量发生变化或 consumer 数量发生变化时

比方说如下的场景:

  1. 日常发布过程中 consumer 实例的停止与启动
  2. Consumer 消费者实例异常宕机
  3. 网络异常导致 consumer 消费者实例和 Broker 断开链接
  4. 主动进行 consumer group 下消费者数量扩容/缩容
  5. Topic queue 主动进行扩容/缩容

在这里插入图片描述

机制剖析

下面是纯理论的知识,具体的逻辑还需要去对照源码进行学习。

Broker 端通过以下三个组件共同维护 consumer group 的元信息:

  • ConsumerManager: ConsumerManager 是最重要的一个消费者组元数据管理器,其维护了某个消费者组的订阅信息,以及所有消费者实例的详细信息,并在发生变化时提供通知机制。
  • ConsumerOffsetManager: 维护 offset 进度信息
  • SubscriptionGroupManager: 运维相关操作信息维护

Broker 在 Rebalance 过程中,是一个协调者的角色,它会在消费者组信息或者 topic 信息发生变化时「通知每个消费者各自 rebalance」,即每个消费者自己给自己重新分配队列,而不是 broker 将分配好的结果通知 consumer.

从这个角度看,RocketMQ 与 Kafka Rebalance 机制类似,二者 Rebalance 分配都是在客户端进行,不同的是:

  • Kafka: 会在消费者组的多个消费者实例中,选出一个作为 Group Leader,由这个 Group Leader 来进行分区分配,分配结果通过 Coordinator(特殊角色的 Broker)同步给其他消费者。相当于 Kafka 的分区分配只有一个大脑,就是 Group Leader.
  • RocketMQ: 每个消费者,自己负责给自己分配队列,相当于每个消费者都是一个大脑。

限制

Topic 的一个队列 queue 最多分配给一个消费者 consumer(不考虑公司内魔改的情况),因此当某个 consumer group 下的消费者实例大于队列的数量时,多余的消费者实例将分配不到任何队列。

危害

Rebalance 时,也会对消费造成一些不良影响,主要原因是由于

  1. Rebalance 期间,消费者需要暂停消费等待 Rebalance 结束
  2. Rebalance 结束后,新连接的消费者需要从之前 queue 已提交的 offset 重新开始消费

在这里插入图片描述

具体的影响面如下所述:

  • 消费暂停:假设 consumer1 当前消费 queue1, queue2 两个队列,当 consumer1 下线触发 rebalance 时,这两个队列就需要暂停,等到重新分配给 consumer2 以后,这两个队列才能继续消费。
    解决方案:做好消费暂停报警,及时感知。
  • 重复消费:consumer2 在消费分配给自己的两个队列时,必须接着从 broker 中获取到 consumer1 已经提交的 offset 的 +1,才开始继续消费。然而默认情况下,offset 是异步提交给 broker 的,比如 consumer1 当前消费到 offset 为 10,但是异步提交给 broker 的 offset 为 8;如果此时 consumer2 从 offset = 8 继续开始消费,就会有两条消息重复。也就是说,consumer2 并不会等待 consumer1 提交完 offset 以后,在进行 rebalance,因此提交间隔越长,造成的重复消费就越多。
    解决方案:这个时候就需要业务接入方能够自己去实现「幂等控制」,基于「一锁二判三更新」的原则,基于状态机、流水表、业务唯一索引进行重复操作判断。
  • 消费突刺:由上面两个问题衍生而来,由于 rebalance 可能导致重复消费,如果需要重复消费的消息过多;或者因为 rebalance 暂停时间过长,导致积压了部分消息,都有可能导致 rebalance 结束之后瞬间需要消费很多消息。
    解决方案:做好集群动态扩容,避免消息堆积;做好消费突刺限流,避免打挂系统和下游

结合前面的 rebalance 触发时机可以看出来,其实这些危害出现的时机并不严格,但是我们平常写业务代码的时候,又几乎没有做消费暂停报警、幂等、消费突刺限流的控制,可谓是面向不稳定的编程了,代码的健壮性想来其实也不算很高,有「代码洁癖」的话,确实是需要再改进下。

但是话说回来,做太严格的控制,有可能会因为场景不复杂,写复杂度较高的代码在 CR 被打回来,原由是过度编程了,这就是大家见仁见智了,团队项目里可以不这么写,但是得懂这种场景可能造成的不良影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网民工蒋大钊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值