首页 > 其他分享 >【RocketMQ】Rebalance负载均衡总结

【RocketMQ】Rebalance负载均衡总结

时间:2023-09-26 09:03:50浏览次数:48  
标签:负载 消费者 队列 粒度 消息 均衡 Rebalance RocketMQ

消费者负载均衡,是指为消费组下的每个消费者分配订阅主题下的消费队列,分配了消费队列消费者就可以知道去消费哪个消费队列上面的消息,这里针对集群模式,因为广播模式,所有的消息队列可以被消费组下的每个消费者消费不涉及负载均衡,而集群模式一个消息队列同一时间只能分配给组内的一个消费者进行消费。

RocketMQ 5.0以前是按照队列粒度进行负载均衡的,5.0以后提供了按消息粒度进行负载均衡。

队列粒度负载均衡

对于4.x/3.x的版本,包括DefaultPushConsumer、DefaultPullConsumer、LitePullConsumer等,默认且仅能使用队列粒度负载均衡策略。
队列粒度负载均衡策略中,同一消费者组内的多个消费者将按照队列粒度消费消息,每个队列只能被其中一个消费者消费。

注:图片来自RocketMQ官方文档

队列粒度负载均衡是在每个消费者端进行的,并不是由某个节点统一进行负载均衡之后将分配结果通知到每个消费者。消费者增加或者减少会影响消息队列的分配,所以Broker需要感知消费者的上下线情况,消费者在启动时会向所有的Broker发送心跳包进行注册,通知Broker消费者上线,下线的时候也会向Broker发送取消注册的请求,Broker会维护消费者信息的注册信息,在消费者发生变更时会通知消费者进行负载均衡。

Rebalance过程

消费者在启动的时候,会立刻触发一次负载均衡,为消费者分配消息队列。为了保证消费者拿到的主题路由信息是最新的(topic下有几个消息队列、消息队列的分布信息等),消费者会向NameServer发送请求,更新每一个主题的路由信息,保证路由信息是最新的。

  1. 根据Topic获取该Topic下的所有消费队列(MessageQueue对象), 消费者在启动时已经向NameServer发送请求获取了最新Topic的路由信息,里面可以获取到Topic下的所有消费队列;

  2. 由于负载均衡是在每个消费者端进行的,负载均衡时还需要知道订阅该主题的消费者组下都有哪些消费者,这个数据可以通过Broker获取,通过向Broker发送请求,查找订阅了该主题的所有消费者的ID(消费者会向Broker注册,所以可以通过Broker查找订阅了某个Topic的消费者);

  3. 如果主题对应的消息队列集合和获取到的消费者ID都不为空,对消息队列集合和消费ID集合进行排序;

  4. 获取分配策略,根据具体的分配策略,为当前的消费者分配对应的消费队列,RocketMQ默认提供了以下几种分配策略:

    • AllocateMessageQueueAveragely:平均分配策略,根据消息队列的数量和消费者的个数计算每个消费者分配的队列个数。
    • AllocateMessageQueueAveragelyByCircle:平均轮询分配策略,将消息队列逐个分发给每个消费者。
    • AllocateMessageQueueConsistentHash:根据一致性 hash进行分配。
    • AllocateMessageQueueByConfig:根据配置,为每一个消费者配置固定的消息队列 。
    • AllocateMessageQueueByMachineRoom:分配指定机房下的消息队列给消费者。
    • AllocateMachineRoomNearby:优先分配给同机房的消费者。
  5. 根据最新分配的消息队列,更新当前消费者负责的消息处理队列;

    由于负载均衡之后,消费者负责的消息队列可能发生变化,所以这里需要更新当前消费者负责的消息队列,之后就可以拉取消息进行消费了。

Rebalance的触发时机

一、消费者启动时触发
消费者在启动时会进行一次负载均衡,为自己分配消息队列。

二、Broker发现消费组变更时触发
处于以下两种情况之一时会被判断为消费组发生了变化,需要进行负载均衡:

(1)某个消费组内有新的消费者向Broker进行了注册,比如某个消费组原来有两个消费者,现在新增了一个消费者,新增的消费者启动时会向Broker发送注册请求;

(2)消费组订阅的主题信息发生了变化,比如消费组新增订阅了某个主题或者取消某个主题的订阅,会被判断为主题订阅信息发生了变化;

被判定为变化之后,会触发变更事件,向该消费者下的所有消费者发送发送变更请求,通知组下每个消费者进行负载均衡。

三、Broker收到消费者下线时触发
如果有消费者向Broker发送UNREGISTER_CLIENT取消注册请求,并且开启了允许通知变更,会触发变更事件,变更事件同上,Broker会通知该消费者组下的所有消费者进行一次负载均衡。

四、消费者定时触发
消费者本身也会定时执行负载均衡,默认是20s执行一次;

负载均衡源码解析可参考:【RocketMQ】【源码】负载均衡源码分析

特点

缺点
(1)队列粒度负载均衡策略分配粒度较大,不够灵活;
(2)队列粒度负载均衡策略保证同一个队列仅被一个消费者处理,在消费者数量、队列数量发生变化时,可能会出现短暂的队列分配结果不一致,从而导致少量消息被重复处理。
(3)如果队列数量和消费者数量不均衡,可能会出现部分消费者空闲或者部分消费者分配到的消息队列过多的情况。

优点
在流式处理场景下有优势,能够保证同一队列的消息被相同的消费者处理,对于批量处理、聚合处理更友好。

消息粒度负载均衡

在RocketMQ 5.0之后,增加了消息粒度负载均衡策略,对于PushConsumer和SimpleConsumer类型的消费者,默认且仅使用消息粒度负载均衡策略。

消息粒度负载均衡策略中,同一消费组内的多个消费者将按照消息粒度平均分摊主题中的所有消息,即同一个队列中的消息,可被平均分配给组内多个消费者共同消费。

注:图片来自RocketMQ官方文档

消息粒度负载均衡策略保证同一个队列的消息可以被组内多个消费者共同处理,但是该策略使用的消息分配算法结果是随机的,不能指定消息被哪一个特定的消费者处理。当消费者获取到某条消息后,服务端会对该消息加锁,保证该消息对其他消费者不可见,直到消息消费成功或者超时,所以多个消费者同时消费同一个消息队列中的消息,服务端也可以保证消息不会被多个消费者重复消费。

特点

(1)消费分摊均衡可以更均匀的分摊消息:不会像队列粒度负载均衡一样,出现分配不平衡的情况。
(2)对非对等消费者更友好:如果网络机房延迟、消费者物理资源规格不一致等原因,按照队列分配消息,可能出现部分消费者堆积、部分消费者空闲的情况,本质还是分摊更均匀。
(3)队列分配运维更方便:队列粒度负载均衡需要保证队列数量大于等于消费者数量,以免某些消费者获取不到队列出现空闲的情况,消息粒度负载均衡无需关注队列的数量。

消息粒度负载均衡策略适用于绝大多数在线处理的业务场景,对于流式处理、聚合计算等场景,更适合队列粒度的负载均衡策略。

参考
RocketMQ官方文档

标签:负载,消费者,队列,粒度,消息,均衡,Rebalance,RocketMQ
From: https://www.cnblogs.com/shanml/p/17718833.html

相关文章

  • 【RocketMQ】事务实现原理总结
    RocketMQ事务的使用场景单体架构下的事务在单体系统的开发过程中,假如某个场景下需要对数据库的多张表进行操作,为了保证数据的一致性,一般会使用事务,将所有的操作全部提交或者在出错的时候全部回滚。以创建订单为例,假设下单后需要做两个操作:在订单表生成订单在积分表增加本次订......
  • RocketMq发送消息之事务消息
    概述事务消息共有三种状态,提交状态、回滚状态、中间状态:TransactionStatus.CommitTransaction:提交事务,它允许消费者消费此消息。TransactionStatus.RollbackTransaction:回滚事务,它代表该消息将被删除,不允许被消费。TransactionStatus.Unknown:中间状态,它代表需要检查消......
  • 使用Consul搭建负载均衡
    一、Consul服务注册发现1.启动Consul:consulagent-dev 2.打开Consul地址,默认8500端口:8500 3.封装静态类,注册Consul服务的方法:usingConsul;usingMicrosoft.Extensions.Configuration;usingSystem;publicstaticclassC......
  • 使用Nginx搭建负载均衡
    1.修改配置文件conf/nginx.conf      2.配置文件中增加服务调用upstreamNET6RC2{server127.0.0.1:5726;server127.0.0.1:5727;server127.0.0.1:5728;server127.0.0.1:5729;}server{......
  • RocketMq发送消息之过滤消息
    过滤消息概述在大多数情况下,TAG是一个简单而有用的设计,其可以来选择您想要的消息。例如://定义一个group1的消费者组DefaultMQPushConsumerconsumer=newDefaultMQPushConsumer("group1");//订阅TOPIC主题中的三个TAG类型的消息consumer.subscribe("TOPIC","TAGA||......
  • RocketMq发送消息之批量消息
    概述批量发送消息能显著提高传递小消息的性能。限制是这些批量消息应该有相同的topic,相同的waitStoreMsgOK,而且不能是延时消息。此外,这一批消息的总大小不应超过4MB发送批量消息如果您每次只发送不超过4MB的消息,则很容易使用批处理,样例如下:Stringtopic="BatchTest";List<M......
  • 负载均衡 —— SpringCloud Netflix Ribbon
    Ribbon简介Ribbon是Netfix客户端的负载均衡器,可对HTTP和TCP客户端的行为进行控制。为Ribbon配置服务提供者地址后,Ribbon就可以基于某种负载均衡算法自动帮助服务消费者去请求。Ribbon默认提供了很多负载均衡算法,例如轮询、随机等,也可以为Ribbon实现自定义的负载均......
  • RocketMq发送消息之延迟消息
    延迟消息比如电商里,提交了一个订单就可以发送一个延时消息,1h后去检查这个订单的状态,如果还是未付款就取消订单释放库存。使用限制对比于rabbitmq中的延迟消息来说,rockermq并不支持任意时间的延迟,需要设置几个固定的延时等级,从1s到2h分别对应着等级1到18级//org/apache/rocket......
  • RocketMQ发送消息之同步异步单向
    官网教程:https://rocketmq.apache.org/zh/docs/quickStart/01quickstart基于双主双从异步方式开启的前提下,在maven项目中引入下列依赖<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.9.1&l......
  • PostgreSQL负载均衡分发与双主HA架构
    一、风哥PG-DBA培训16:PostgreSQL负载均衡分发与双主HA架构本课程由风哥发布的基于PostgreSQL数据库的系列课程,本课程属于PostgreSQL主从复制与高可用集群阶段之PostgreSQL负载均衡分发与双主HA架构,学完本课程可以掌握PostgreSQL高可用负载均衡解决方案,PostgreSQL+Keepalived流复......