RocketMQ基本概念!

官网:https://rocketmq.apache.org/

中文文档:https://github.com/apache/rocketmq/tree/master/docs/cn

最佳实践:https://github.com/apache/rocketmq/blob/master/docs/cn/best_practice.md

设计文档:https://github.com/apache/rocketmq/blob/master/docs/cn/design.md

Topic:

一类消息的集合,消息发送者将一类消息发送到一个主题中。

例如订单模块将订单发送到 order_topic 中,而用户登录时,将登录事件发送到 user_login_topic 中。

标签(Tag):

消息设置的标志,用于同一Topic下区分不同类型的消息,可以根据Topic+Tag实现消息的精细化生产和消费。

ConsumeGroup:

消息消费组,一个消费组拥有多个消费者,消费组首先在启动时需要订阅需要消费的Topic。

  • 一个Topic可以被多个消费组订阅,同样一个消费组也可以订阅多个主题。

队列(Queue)

一个Topic可以有很多队列,消息都存在Queue上,默认是一个Topic在同一个Broker组中是4个。

  • 如果一个Topic现在在2个Broker组中,那么就有可能有8个队列。

由于一个Topic可能会有很多的队列,消息发送到哪个队列上?

RocketMQ提供了两种消息队列的选择算法:

  • 轮询算法。
  • 最小投递延迟算法。

轮询算法:

  • 一个队列一个队列发送消息,这些就能保证消息能够均匀分布在不同的队列下,默认的队列选择算法。

最小投递延迟算法:

  • 每次消息投递的时候会统计投递的时间延迟,在选择队列的时候会优先选择投递延迟时间小的队列。
  • 这种算法可能会导致消息分布不均匀的问题。

消费模式

集群模式:

同一Topic下的一条消息只会被同一消费组中的一个消费者消费。

  • 消息被负载均衡到了同一个消费组的多个消费者实例上。

图片

广播消费:

每条消息推送给集群内所有的消费者,保证消息至少被每个消费者消费一次。

  • 通常用于刷新内存缓存。

图片

Confirm机制

消息生产者把消息发送给MQ,如果接收成功,MQ会返回一个ACK消息给生产者。

如果消息接收不成功,MQ会返回一个Nack消息给生产者。

img

重试机制

集群消费下,重试机制的本质是 RocketMQ 的延迟消息功能。

Broker 端会为每个 Topic 创建一个重试队列

  • 队列名称是:%RETRY% + 消费者组名

达到重试时间后将消息投递到重试队列中进行消费重试(消费者组会自动订阅重试 Topic)。

最多重试消费 16 次,重试的时间间隔逐渐变长。

  • 若达到最大重试次数后消息还没有成功被消费,则消息将被投递至死信队列

死信队列

死信队列用于处理无法被正常消费的消息。

  • 当一条消息初次消费失败,消息队列会自动进行消息重试。

  • 达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息。

    • 此时,消息队列不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中。

RocketMQ将这种正常情况下无法被消费的消息称为死信消息,将存储死信消息的特殊队列称为死信队列。

Queue分配算法

一个Topic中的Queue只能由Consumer Group中的一个Consumer进行消费。

  • 而一个Consumer可以同时消费多个Queue中的消息。

那么QueueConsumer间的配对关系是如何确定的,即Queue要分配给哪个Consumer进行消费?

常见的有四种策略,分别是:

  • 平均分配策略、环形平均策略、一致性Hash策略、同机房策略。

  • 这些策略是通过在创建Consumer时的构造器传进去的。

平均分配策略(默认):

该算法是根据:Avg = QueueCount / ConsumerCount的计算结果进行分配的。

如果能够整除,则按顺序将AvgQueue逐个分配,如果不能整除。

  • 则将多余出的Queue按照Consumer顺序逐个分配。

img

环形分配策略:

环形平均算法是指,根据消费者的顺序,依次由Queue队列组成的环形图逐个分配,该方法不需要提前计算。

img

一致性哈希分配策略:

该算法会将ConsumerHash值作为Node节点存放到Hash环上,然后将QueueHash值也放到Hash环上。

通过顺时针方向,距离Queue最近的那个Consumer就是该Queue要分配的Consumer

一致性哈希算法可以有效减少由于消费者组扩容或缩容所带来的大量的Rebalance

  • 所以它适合用在Consumer数量变化较频繁的场景。

但是一致性哈希算法也存在不足,就是分配效率较低,容易导致分配不均的情况。

即每个消费者消费的队列数,有可能相差很大,这样就会造成个别消费者压力过大。

  • 可以引入虚拟桶,让QueueHash环中尽可能分配均匀。

img

机房分配策略:

该算法会根据Queue的部署机房位置和Consumer的位置,过滤出当前Consumer相同机房的Queue

然后按照平均分配策略或环形平均策略对同机房Queue进行分配。

如果没有同机房Queue,则按照平均配策略或环形平均策略对所有Queue进行分配。

img

消息过滤

RocketMQ的消费者可以根据Tag进行消息过滤,也支持自定义属性过滤。

消息过滤目前是在Broker端实现的:

  • 优点是减少了对于Consumer无用消息的网络传输。

  • 缺点是增加了Broker的负担、而且实现相对复杂。

RocketMQ支持两种方式的消息过滤:

  • 一种是Tag过滤,另外一种是SQL过滤。