> 文档中心 > RocketMQ(六)RocketMQ消息的类型、模式、负载均衡

RocketMQ(六)RocketMQ消息的类型、模式、负载均衡

目录

  • 1、消费类型
    • 1)拉取式消费
    • 2)推送式消费
    • 3)对比
  • 2、消费模式
    • 1)广播模式
    • 2)集群模式(默认)
    • 3)消息进度保存
  • 3、消息负载均衡(Rebalance机制)
    • 1)Rebalance限制
    • 2)Rebalance危害
    • 3)Rebalance原因及过程
  • 4、Queue分配算法
    • 1)平均分配策略
    • 2)环形平均策略
    • 3)一致性hash策略
    • 4)同机房策略

1、消费类型

消费者从Broker中获取消息的方式有两种:pull拉取方式和push推动方式。

1)拉取式消费

​ Consumer主动从Broker中拉取消息,主动权由Consumer控制。一旦获取了批量消息,就会启动消费过程。不过,该方式的实时性较弱,即Broker中有了新的消息时消费者并不能及时发现并消费。

拉取时间间隔是由用户指定,所以在设置该间隔时需要注意:间隔太短,空请求比例会增加;间隔太长,消息的实时性太差

2)推送式消费

​该模式下Broker收到数据后会主动推送给Consumer,该获取方式一般实时性较高。

​该获取方式是典型的发布-订阅模式,即Consumer向其关联的Queue注册了监听器,一旦发现有新的消息到来就会触发回调,去Queue中拉取消息。而这些都是基于Consumer与Broker间的长连接的,长连接的维护是需要消耗系统资源的。

3)对比

  • pull需要应用去实现对关联Queue的遍历,实时性差;但便于应用控制消息的拉取
  • push:封装了对关联Queue的遍历,实时性强,但会占用较多的系统资源

2、消费模式

1)广播模式

​ 广播消费模式下,相同Consumer Group的每个Consumer实例都接收同一个Topic的全量消息。即每条消息都会被发送到Consumer Group中的每个Consumer进行消费。

消息被所有的consumer进行消费。
在这里插入图片描述

2)集群模式(默认)

​集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊同一个Topic的消息。即每条消息只会被发送到Consumer Group中的某个Consumer。

  • 一条消息只会被同Group中的一个Consumer消费
  • 多个Group同时消费一个Topic时,每个Group都只会有一个Consumer消费到数据
    在这里插入图片描述

3)消息进度保存

  • 广播模式: 消费进度保存在consumer端。因为广播模式下consumer group中每个consumer都会消费所有消息,但它们的消费进度是不同。所以consumer各自保存各自的消费进度。

  • 集群模式: 消费进度保存在broker中。consumer group中的所有consumer共同消费同一个Topic中的消息,同一条消息只会被消费一次。消费进度会参与到了消费的负载均衡中,故消费进度是需要共享的。

3、消息负载均衡(Rebalance机制)

只有集群模式的消费者才会存在负载均衡;

消费者负载均衡,指的是,将⼀个Topic下的多个Queue分配到不同Consumer实例的过程。

负载均衡机制的本意是为了提升消息的并行消费能力。例如,⼀个Topic下5个队列,在只有1个消费者的情况下,这个消费者将负责消费这5个队列的消息。如果此时我们增加⼀个消费者,那么就可以给其中⼀个消费者分配2个队列,给另⼀个分配3个队列,从而提升消息的并行消费能力。

通过增加consumer实例去分摊queue的消费,可以起到水平扩展的消费能力的作用。而有实例下线的时候,会重新触发负载均衡,这时候原来分配到的queue将分配到其他实例上继续消费。

在这里插入图片描述
默认的分配算法是AllocateMessageQueueAveragely,如下图:
在这里插入图片描述

还有另外一种平均的算法是AllocateMessageQueueAveragelyByCircle,也是平均分摊每一条queue,只是以环状轮流分queue的形式,如下图:

在这里插入图片描述

需要注意的是,集群模式下,queue都是只允许分配只一个实例,否则会导致同一个消息在不同的实例下被消费多次,所以算法上都是一个queue只分给一个consumer实例,一个consumer实例可以允许同时分到不同的queue。

1)Rebalance限制

由于⼀个队列最多分配给⼀个消费者,因此当某个消费者组下的消费者实例数量大于队列的数量时,多余的消费者实例将分配不到任何队列,所以需要控制让queue的总数量大于等于consumer的数量。

2)Rebalance危害

  • 消费暂停: 在只有一个Consumer时,其负责消费所有Queue;在新增了一个Consumer后会触发Rebalance的发生。此时原Consumer就需要暂停部分队列的消费,等到这些队列分配给新的Consumer后,这些暂停消费的队列才能继续被消费。

  • 消费重复: Consumer 在消费新分配给自己的队列时,必须接着之前Consumer 提交的消费进度的offset继续消费。然而默认情况下,offset是异步提交的,如果异步提交失败了,就会导致提交到Broker的offset与Consumer实际消费的消息并不一致。这个不一致的差值就是可能会重复消费的消息。

    同步提交: consumer提交了其消费完毕的一批消息的offset给broker后,需要等待broker的成功ACK。当收到ACK后,consumer才会继续获取并消费下一批消息。在等待ACK期间,consumer是阻塞的。

    异步提交: consumer提交了其消费完毕的一批消息的offset给broker后,不需要等待broker的成功ACK。consumer可以直接获取并消费下一批消息。

  • 消费突刺: 由于Rebalance可能导致重复消费,如果需要重复消费的消息过多,或者因为Rebalance暂停时间过长从而导致积压了部分消息。那么有可能会导致在Rebalance结束之后瞬间需要消费很多消息。

3)Rebalance原因及过程

Rebalance产生的原因:
导致Rebalance产生的原因:消费者所订阅Topic的Queue数量发生变化,或消费者组中消费者的数量发生变化。

Rebalance过程:

​ 在Broker中维护着多个Map集合,这些集合中动态存放着当前Topic中Queue的信息、Consumer Group中Consumer实例的信息。一旦发现消费者所订阅的Queue数量发生变化,或消费者组中消费者的数量发生变化,立即向Consumer Group中的每个实例发出Rebalance通知。

​ Consumer实例在接收到通知后会采用Queue分配算法自己获取到相应的Queue,即由Consumer实例自主进行Rebalance。

4、Queue分配算法

一个Topic中的Queue只能由Consumer Group中的一个Consumer进行消费,而一个Consumer可以同时消费多个Queue中的息。那么Queue与Consumer间的配对关系是如何确定的,即Queue要分配给哪个Consumer进行消费,也是有算法策略的,这些策略是通过在创建Consumer时的构造器传进去的。

常见的有四种策略:平均分配、环形平均策略、一致性hash策略、同机房策略。

1)平均分配策略

该算法是要根据avg = QueueCount / ConsumerCount的计算结果进行分配的。如果能够整除,则按顺序将avg个Queue逐个分配Consumer;如果不能整除,则将多余出的Queue按照Consumer顺序逐个分配。
比如:有10个Queue,4个Consumer,那么每个Consumer可以分配到2个Queue,但是还有两个Queue是多余的,那么这两个Queue将依次按顺序分给Consumer-A,Consumer-B

在这里插入图片描述

该算法:先计算好每个Consumer应该分得几个Queue,然后再依次将这些数量的Queue逐个分配个Consumer。

2)环形平均策略

环形平均算法是指,根据消费者的顺序,依次在由queue队列组成的环形图中逐个分配。
在这里插入图片描述

该算法不用事先计算每个Consumer需要分配几个Queue,直接一个一个分即可。

3)一致性hash策略

该算法会将consumer的hash值作为Node节点存放到hash环上,然后将queue的hash值也放到hash环上,通过顺时针方向,距离queue最近的那个consumer就是该queue要分配的consumer。

在这里插入图片描述

该算法存在的问题:分配不均,其可以有效减少由于消费者组扩容或缩容所带来的大量的Rebalance。

4)同机房策略

在这里插入图片描述

该算法会根据queue的部署机房位置和consumer的位置,过滤出当前consumer相同机房的queue。然后按照平均分配策略或环形平均策略对同机房queue进行分配。如果没有同机房queue,则按照平均分配策略或环形平均策略对所有queue进行分配。