负载均衡算法是消息系统中不可缺少的算法策略,看过Rocketmq的消费者负载均衡实现后,发现在设计和实现上非常巧妙,所以今天我们将它记录下来,和大家一起分享,也希望对大家有些帮助。
|什么是负载均衡技术呢?
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。
我们可以简单理解成,负责均衡技术是为了最大化让计算机资源分配更加合理,最终目的是为了资源合理利用。
在Rocketmq中,有两个地方需要使用到负载均衡技术
1、生产者发送消息
为了让消息均衡发送到broker中的queue中
2、消费者消费消息(本文着重分析的内容)
为了让消息均衡分配给不同的消费者线程
上文分析过Rocketmq消费者消息流程,其中消息过程中最重要的一步就是通过负载均衡算法获取一个准备拉取消息目标MessageQueue,如下图第2步。
Rocketmq消费者消费负载均衡实现在消费者客户端实现。位于
org.apache.rocketmq.client.consumer.rebalance包,包括按最近机房,平均等负载算法实现,默认使用平均算法(AllocateMessageQueueAveragely)。
本文将主要分析averagely和averagelyByCircle算法,为了说明这两种分配算法的分配规则,现在对 16 个队列,进行编号,用 q0~q15 表示, 消费者用 c0~c2 表示。
1、averagely-范围平均算法
AllocateMessageQueueAveragely分配算法的队列负载机制如下:
c0:q0 q1 q2 q3 q4 q5
c1: q6 q7 q8 q9 q10
c2: q11 q12 q13 q14 q15
其算法的特点是用总数除以消费者个数,余数按消费者顺序分配给消费者,故 c0 会多 分配一个队列,而且队列分配是连续的
范围平均算法实现如下:
//消费者数量
List<String> cidAll = new ArrayList<>();
cidAll.add("126");
cidAll.add("127");
cidAll.add("128");
cidAll.add("129");
cidAll.add("130");
String currentCID = "130";
int index = cidAll.indexOf(currentCID);
//消息队列数量
List<String> mqAll = new ArrayList<>();
mqAll.add("1");
mqAll.add("2");
mqAll.add("3");