RocketMQ—高可用集群篇
Posted 敲代码的小小酥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RocketMQ—高可用集群篇相关的知识,希望对你有一定的参考价值。
一、集群的模式
首先要明确两个概念:
Master:主节点,可以进行读和写操作。
Slave:从节点,只可以读,不进行写操作。
也就是 Producer 只能和 Master 角色的 Broker 连接写入消息;Consumer 可以连接 Master 角色的 Broker,也可以连接 Slave 角色的 Broker 来读取消息。
Master 和 Slave 的区别:在 Broker 的配置文件中,参数 brokerId 的值为 0 表明这个 Broker 是 Master,大于 0 表明这个 Broker 是 Slave,同时 brokerRole 参数也会说明这个 Broker 是 Master 还是 Slave。
-
单master模式
就是单机模式,不是高可用集群模式。 -
多master模式
多个master节点构成的集群。单个master宕机对应用没有影响。
优点:多master集群,一个topic在每个master中都有,相当于对topic进行了横向扩展。当有很多生产者往topic中发送消息时,可以负载到多个master节点上,提高写入数据的效率。
缺点:如果某个master宕机,则这个master上的数据将不可用。根本原因还是没有对master上的数据进行主从备份的原因。多个master节点各自存着自己的数据,不会相互备份。
- 多master多slave模式
上面多master模式提到,没有slave节点的话,master节点的数据很容易造成丢失。所以,我们需要给每个master节点配备slave节点,就形成了多master多slave模式。生产者发送消息至master,master再copy消息至slave节点,进行消息的备份。在copy数据时,又分为同步复制和异步复制两种模式。
异步复制:
生产者发送消息至master后,master就会反馈给生产者消息发送成功。master会单独开启一个线程,将数据copy到slave中。这样造成的风险就是如果master挂了,而数据还没有copy到slave节点,就会造成数据的丢失。
同步复制:
生产者发送消息至master节点后,master节点copy数据到slave节点。当copy成功时,master节点才会告诉生产者,消息发送成功。这样保证了数据的备份,但是会影响性能。为了高可用,还是要选择这种模式,因为选用异步模式,根本没解决多master模式所造成的问题。
在多主多从模式中,一台master挂掉之后,数据就不会再写入这台master中。但是这台master对应的slave节点,还可以继续让消费者消费消息。
结论:
RocketMQ集群模式推荐 使用多主多从同步模式。生产者发送消息第一时间是存入内存中的,要持久化消息,需要刷盘刷到磁盘中。我们做了同步复制消息后,就可以采用异步刷盘的方式,将消息进行持久化。这样避免刷盘对性能造成的影响。
在集群中,NameServer之间是没有通信的,多个NameServer之间只是 数据的备份。所以NameServer服务器选两台就够了
由上面的分析可以知道,RocketMQ的高可用集群,所需要的服务器数量是比较多的,且RocketMQ本身对内存的要求也比较高。所以对于大部分中小型企业来说,在数据量不大的情况下,还是rabbitMQ是最好的选择。
如果想使用RocketMQ,还要节约成本的话,就选择一主一从的模式。一主的模式就是缺少横向扩展能力,topic支持的并发量不能横向扩展。但是RocketMQ单机支持的并发量也很多。
注意:
在集群中,NameServer没有选举的功能,一台master挂了之后,与之对应的slave节点不会自动选举为master节点。需要我们手动处理,改slave节点的配置文件,把它改成主节点。或者修复挂掉的主节点。
二、集群搭建
集群的搭建这里不进行讲解,官网和其他网站资料很多,可以进行参考。
三、消息生产的高可用机制
- 选择队列策略
默认采用轮询的方式选择Broker和MessageQueue。也就是有几台master主机,每个topic下有几个MessageQueue,都会平均的分配消息。最终的结果就是一个topic上的消息平均散落在不同Broker的不同MessageQueue上。
所以,一个Topic上的消息,会在不同的master上存储,并不是在一台主机上存储。当一个master挂掉之后,其保存的数据,会在对应的slave节点有备份。 - 规避策略
当生产者消息发送失败时,会进行消息重试。重试时,消息会发送到另一台主Broker上,不会再发送到第一次失败的master上。这就是规避策略。
需要注意的是,默认情况下,只是重试的消息,会自动切换到另一个master上。而下一条新的消息,还会发往之前消息发送失败的master上。如果发送失败,走重试的话,才会自动切换到另外一个master上。
我们可以通过设置生产者的属性,让其在有消息失败时,就把所有的消息切换到另外的master上,设置如下:
设置成true后,在一段时间内,所有的新消息和重试消息,都不会再发往接收失败的master主机上。一段时间过后,才会再往那个master上发消息。具体的时间算法,由RocketMQ自己维护,我们无需关注。
在实际应用中,我们使用默认机制即可。无需将上面的参数设置成true。因为NameServer对各个Broker之间的状态监听,存在延迟机制。即某个Broker挂了,可能在一段时间后,NameServer才会感知到。那么在这段时间内,发送到挂了的Broker上的消息,就会进行重试,发往另一台正常运行的Broker上。NameServer感知到Broker挂掉所需的时间并不长,完全可以接受这个延迟所造成的消息重发。所以我们可以选择默认的设置。反倒是假如我们设置成了true。那么在一段时间内,消息接收失败的Broker是不可用的。假如是因为网络波动造成了某个消息的接收失败,就让这个Broker在一段时间内不可用,这明显是对资源的浪费,且还会影响RocetMQ集群的并发量。所以,不推荐将上面的参数设置成true.
四、消费高可用机制
- 当master节点挂掉之后,消费者会从slave节点读数据。当master节点繁忙(服务器的内存不足)的时候,消费者也会从slave节点读数据。
- 消费者消费失败的数据,有重试机制,设定为CONSUME_LATER的数据,会进入重试主题,而不是继续在原主题中继续进行消费。
重试主题是RocketMQ自动生成的主题,其命名规则是%RETRY%+消费者群组名称,如下图所示:
对于有顺序保障的消息而言,这种重试机制就不可用了,因为会造成消息的不顺序消费。对于其他的消息,如普通消息,延时消息等消息,都可以用重试机制。
重试机制的触发:
在消费者客户端,只有返回CONSUMMER_SUCESS,RocketMQ才会认为消息消费成功了,不进行重试。如果返回null,或者消费者程序抛出异常,那么都会触发重试机制。
进入重试主题的消息,会继续给该消费者群组消费。默认可以重试16次。每次重试都有固定的时间间隔。16次重试下来,需要花费4个多小时。如果这16次重试依旧没有消费成功消息,那么这个消息就会进入死信队列。
死信队列的消息消费者就无法消费了,需要程序员手动处理死信队列的数据。可以通过RocketMQ控制台查看死信消息。
以上是关于RocketMQ—高可用集群篇的主要内容,如果未能解决你的问题,请参考以下文章