RocketMq的负载均衡

RocketMq的部署方式


NameServer集群

提供轻量级的服务发现和路由。每个NameServer 记录完整的路由信息,提供等效的读写服务,并支持快速存储扩展。

就是一个注册中心,存储当前集群所有Brokers信息、Topic跟Broker的对应关系。

Namesrv用于存储Topic、Broker关系信息,功能简单,稳定性高。多个Namesrv之间相互没有通信,单台Namesrv宕机不影响其他Namesrv与集群;即使整个Namesrv集群宕机,已经正常工作的Producer,Consumer,Broker仍然能正常工作,但新起的Producer,Consumer,Broker就无法工作。

Namesrv压力不会太大,平时主要开销是在维持心跳和提供Topic-Broker的关系数据。但有一点需要注意,Broker向Namesr发心跳时,会带上当前自己所负责的所有Topic信息,如果Topic个数太多(万级别),会导致一次心跳中,就Topic的数据就几十M,网络情况差的话,网络传输失败,心跳失败,导致Namesrv误认为Broker心跳失败。

producer集群

生产者,产生消息的实例,拥有相同Producer Group 的Producer 组成一个集群。

Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

Producer Group

用来表示一个发送消息应用,一个Producer Group下包含多个Producer实例,可以是多台机器,也可以是一台机器的多个进程,或者一个进程的多个Producer对象。一个Producer Group可以发送多个Topic消息,Producer Group作用如下:

• 标识一类Producer

• 可以通过运维工具查询这个发送消息应用下有多个Producer实例

• 发送分布式事务消息时,如果Producer中途意外宕机,Broker会主动回调Producer Group内的任意一台机器来确认事务状态。

consumer集群

消息消费者,简单来说,消费MQ 上的消息的应用程序就是消费者,至于消息是否进行逻辑处理,还是直接存储到数据库等取决于业务需要。拥有相同Consumer Group 的

Consumer 组成一个集群。

Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。

Consumer Group

用来表示一个消费消息应用,一个Consumer Group下包含多个Consumer实例,可以是多台机器,也可以是多个进程,或者是一个进程的多个Consumer对象。一个Consumer Group下的多个Consumer以均摊方式消费消息,如果设置为广播方式,那么这个Consumer Group下的每个实例都消费全量数据。

broker集群

通过提供轻量级的Topic 和Queue 机制来处理消息存储,同时支持推(push)和拉(pull)模式以及主从结构的容错机制。

集群最核心模块,主要负责Topic消息存储、管理和分发等功能。

单个Broker跟所有Namesrv保持心跳请求,心跳间隔为30秒,心跳请求中包括当前Broker所有的Topic信息。Namesrv会反查Broer的心跳信息,如果某个Broker在2分钟之内都没有心跳,则认为该Broker下线,调整Topic跟Broker的对应关系。但此时Namesrv不会主动通知Producer、Consumer有Broker宕机。

Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。

消息发送

producer的消息发送流程;

• 所有producer的send()方法都调用了defaultMqProducer.send()方法;

• 这也是为什么我们需要对每一个pdoducer进行配置的原因;


生产者发送时,会自动轮询当前所有可发送的broker,一条消息发送成功,下次换另外一个broker发送,以达到消息平均落到所有的broker上。

这里需要注意一点:假如某个Broker宕机,意味生产者最长需要30秒才能感知到。在这期间会向宕机的Broker发送消息。当一条消息发送到某个Broker失败后,会往该broker自动再重发,假如还是发送失败,则抛出发送失败异常。业务捕获异常,重新发送即可。

TopicPublishInfo类是用于producer端做负载均衡的关键类,producer通过这个类来识别broker并选择broker;


MessageQueue类:


描述了单个消息队列的模型;

• 这个队列用于管理哪个topic以及这个队列在哪个broker里

TopicRouteData类:


Topic路由信息集中管理了当前topic下的所有队列信息和broker信息;

• brokerdata中包含了该broker的brokerGroup名字和物理地址;

producer的负载均衡

producer的负载均衡由MQFaultStratage.selectOneMessageQueue()实现

MQFaultStratage这个类是MQ负载均衡的核心类

这个类描述了MQ负载均衡的策略

如何选择一个broker达到负载均衡

• 1.尽量不要选择刚刚选择过的broker

• 2.不要选择延迟容错内的broker

随机选择broker


producer每次在使用broker的时候会记录这次使用的是哪个broker;下次在选取broker的时候主动排除这个broker;

• 在未推送任何消息时,producer中的mq为空,此时lastBrokerName也为空;

• 选择broker是负载均衡的关键,基于方法selectOneMessageQueue(),这个方法会随机选择一个broker;

避开上次选取的broker


当延迟容错未开启时

延迟容错下选择broker


遍历所有broker直至找到一个broker可用(不在延迟容错里或已经可以从延迟容错里去除);如果所有broker都不可用则随机选取一个;

consumer的负载均衡




consumer在启动的时候会实例化rebalanceImpl,这个类负责消费端的负载均衡

MqClientInstance里会调用doRebalance()来进行负载均衡;

• consumer负载均衡是指将topicMessageQueue中的消息队列分配到消费者组的具体消费者里去;

• consumer的负载均衡由rebalanceImpl调用allocateMesasgeQueueStratage.allocate()完成;

• 每次有新的consumer加入group就会重新做一下负载;

• 每10秒自动做一次负载;

allocateMesasgeQueueStratage.allocate()

consumer负载均衡有6种模式:

• 分页模式(随机分配模式)

• 手动配置模式

• 指定机房模式

• 就近机房模式

• 统一哈希模式

• 环型模式

你可能感兴趣的:(RocketMq的负载均衡)