RocketMQ集群核心概念 生产者端的负载均衡
·
Producer的负载均衡
Producer端在发送消息的时候,会先根据Topic找到指定的TopicPublishInfo,在获取了TopicPublishInfo路由信息后,RocketMQ的客户端在默认⽅式下selectOneMessageQueue()⽅法会从TopicPublishInfo中的messageQueueList中选择⼀个队列(MessageQueue)进⾏发送消息。
具体的容错策略均在MQFaultStrategy这个类中定义。
这⾥有⼀个sendLatencyFaultEnable开关变量,如果开启,在随机递增取模的基础上,再过滤掉not available的Broker代理。所谓的"latencyFaultTolerance", 是指对之前失败的,按⼀定的时间做退避。例如,如果上次请求的latency超过550Lms,就退避3000Lms;超过1000L,就退避60000L;
如果关闭,采⽤随机递增取模的⽅式选择⼀个队列(MessageQueue)来发送消息,latencyFaultTolerance机 制是实现消息发送⾼可⽤的核⼼关键所在。
在Rocketmq里面,负载均衡分成了两个部分,一个是生产者的负载均衡,另外一个是消费者的负载均衡。
RocketMQ中的负载均衡都在Client端完成,具体来说的话,主要可以分为Producer端发送消息时候的负载均衡和Consumer端订阅消息的负载均衡。
生产者要去发送消息,这个消息会往某个topic上去发,这个topic会分布在两个broker上面,然后每个broker上面有4个队列。也就是消息会发到某个broker上面的某个队列上面,这个时候就和生产者的负载均衡有关系了。

其实看源码也就是一个一个队列按照顺序发,其实生产端的负载均衡就是一个一个下来。


在发送第一次的时候是brokera上面的最后一个队列,然后是brokerb上面的0号队列,再是1 2 3号。再按照顺序是brokera的0号,1 2 3号。在会话中每一条消息能够按照轮询的方式找到队列然后顺序发送过去。
Consumer的负载均衡
在RocketMQ中,Consumer端的两种消费模式(Push/Pull)都是基于拉模式来获取消息的,⽽在Push模式只是对pull模式的⼀种封装,其本质实现为消息拉取线程在从服务器拉取到⼀批消息后,然后提交到消息消费线程池后,⼜“⻢不停蹄”的继续向服务器再次尝试拉取消息。如果未拉取到消息,则延迟⼀下⼜继续拉取。
在两种基于拉模式的消费⽅式(Push/Pull)中,均需要Consumer端在知道从Broker端的哪⼀个消息队列—队列中去获取消息。因此,有必要在Consumer端来做负载均衡,即Broker端中多个MessageQueue分配给同⼀个ConsumerGroup中的哪些Consumer消费。
注意,在MessageQueue和Consumer之间⼀旦发⽣对应关系的改变,就会触发 rebalance,进⾏重新分配。

两个消费者属于同一个消费组,按照逻辑是一个队列只能被一个消费组里面的一个消费者消费。现在其中一个队列被消费者消费。
比如第一个消费者消费到的队列是比较多的,消费了6个队列,但是第二个消费者只消费了两个队列,所以负载并不均衡。

所以这个时候如何去分配?Consumer的负责均衡可以通过consumer的api进⾏设置:
consumer.setAllocateMessageQueueStrategy(newAllocateMessageQueueAveragelyByCircle());
AllocateMessageQueueStrategy接⼝的实现类表达了不同的负载均衡策略:
a.AllocateMachineRoomNearby :基于机房近侧优先级的代理分配策略。可以指定实际的分配策略。如果任何使⽤者在机房中活动,则部署在同⼀台机器中的代理的消息队列应仅分配给这些使⽤者。否则,这些消息队列可以与所有消费者共享,因为 没有活着的消费者可以垄断它们
b.AllocateMessageQueueAveragely:平均哈希队列算法(默认使用)

c.AllocateMessageQueueAveragelyByCircle:循环平均哈希队列算法
d.AllocateMessageQueueByConfig:不分配,通过指定MessageQueue列表来消费
e.AllocateMessageQueueByMachineRoom:机房哈希队列算法,如⽀付宝逻辑机房
f.AllocateMessageQueueConsistentHash:⼀致哈希队列算法,带有虚拟节点的⼀致性
哈希环。
更多推荐
所有评论(0)