RabbitMQ可用性和可靠性分析

简介: 本文分析一下RabbitMQ的可用性和可靠性。

本文分析一下RabbitMQ的可用性和可靠性。分析一下RabbitMQ如何在可用性和可靠性之间进行权衡的。

1. 基本概念。

首先,介绍几个RabbitMQ的重要的基本概念。这些概念是理解RabbitMQ的可用性和可靠性的基础。

镜像队列(Mirrored Queue)

RabbitMQ集群的队列(Queue)在默认的情况下只存在单一节点(node)上。但是,我们也可以把队列配置成同时存在在多个节点上,也就是说队列可以被镜像到多个节点上。发布(publish)到镜像队列上的消息(message)会被复制(replicated)到说有的节点上。一个镜像队列包含一个主(master)和多个从(slave)。

非同步的Slave (unsynchronised slave)

在很多其他产品中,同步(Synchronation)这个词是和异步(Asynchronation)对立使用。但在RabbitMQ中,同步(synchronised)这个词是和非同步(unsynchronised)这个词对立的。这有什么区别那?在rabbitmq中同步(synchronised)是用来描述master和slave之间的数据状态是否一致的。如果slave包含master中的所有message,则这个slave是synchronised,如果这个slave并没有包含所有master中的message,则这个slave是unsynchronised。同步与异步的对立使用的典型的例子是mysql的主从数据复制,数据复制过程可以分为同步复制和异步复制。

在什么情况下会出现unsynchronised slave?

当一个新slave加入到一个镜像队列时,这时这个新slave是空的,而master中这时可能包含之前接收到的消息。假设这时master包含了5条消息,这是第6条消息被添加到这个镜像队列中,这个新slave会从这个第6条消息开始接收。这时这个slave就是unsynchronised slave。随着前5条消息从镜像队列中被消费掉(consumed), 这个slave变成了synchronised。

另外一种情况,slave 重新加入(rejoin) 到镜像队列时,也会出现非同步的情况。一个slave出于很多情况会重新加入镜像队列,网络分区(network partition)就可能导致这种情况。一个slave要重新加入镜像队列之前,slave可能已经接收了一些消息,它要重新加入镜像队列,就要清空自己之前已经接收的所有消息,好像自己是第一次加入队列一样。

选主方式

由于RabbitMQ的slave加入和重新加入队列的方式,我们得出一个结论,越早加入队列的slave,越有更大的机会是同步状态的,所以RabbitMQ通过这种方式选主:但master因为某种原因消失时,最老的slave被提升成master。

2. RabbitMQ的可用性(Availablity)和数据可靠性(Reliability)

接下来,我们分析一下RabbitMQ的可用性(Availablity)和数据可靠性(Reliability)。RabbitMQ通过参数配置的方式,在可用性(Availablity)和数据可靠性(Reliability)做出了一定的权衡。下面我们来看看这些参数。

参数ha-sync-mode

镜像队列有一个配置参数ha-sync-mode,这个参数有2中取值:automatic, manual。

manual是默认值。如果镜像队列被设置成munual,当一个slave加入和重新加入队列时的行为,就是我们上面描述的行为,之所以叫manual,就是我们可以通过命令行手工(manually)进行同步。命令如下:
rabbitmqctl sync_queue name

如果镜像队列被设置成automatic,当一个新slave加入时,slave会自动同步master中的所有消息,直到所有消息被同步完成之前,所有的操作都会被阻塞(blocking)。

这个参数是可用性和可靠性的一个平衡,manual不保证数据可靠性,在某些情况会出现丢消息的可能,但是保证了队列的可用性。automatic提高了数据的可靠性,但是当有新slave加入时,可能会出现队列的暂时不可用。

参数ha-promote-on-shutdown

镜像队列的另外一个参数ha-promote-on-shutdown,也在可用性和可靠性之间做了一个平衡。ha-promote-on-shutdown有2个取值:when-synced,always。默认是when-synced。ha-promote-on-shutdown是用来控制选主的行为的。

当取值为when-synced时,在可控的master关闭时(比如停止RabbitMQ服务或者关闭操作系统),RabbitMQ会拒绝故障恢复(fail over)到一个非同步slave,也即拒绝把一个非同步的slave提升成新的master。只有在非可控的master关闭时(比如server crash, 断网),才会故障恢复到一个非同步的slave。

当取值为always时,则在所有情况下,都不会拒绝故障恢复到非同步的slave。

很明显,这个参数也是平衡可用性和可靠性的,当when-synced,可靠性更好,可用性降低了,因为如果所有的slave都是非同步状态,那就没有符合条件的slave可以被提升成master,这时队列就处在不可用状态。

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
消息中间件 监控 数据挖掘
基于RabbitMQ与Apache Flink构建实时分析系统
【8月更文第28天】本文将介绍如何利用RabbitMQ作为数据源,结合Apache Flink进行实时数据分析。我们将构建一个简单的实时分析系统,该系统能够接收来自不同来源的数据,对数据进行实时处理,并将结果输出到另一个队列或存储系统中。
1603 2
|
消息中间件 架构师 Java
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
|
存储 消息中间件 缓存
RocketMQ原理—3.源码设计简单分析下
本文介绍了Producer作为生产者是如何创建出来的、启动时是如何准备好相关资源的、如何从拉取Topic元数据的、如何选择MessageQueue的、与Broker是如何进行网络通信的,Broker收到一条消息后是如何存储的、如何实时更新索引文件的、如何实现同步刷盘以及异步刷盘的、如何清理存储较久的磁盘数据的,Consumer作为消费者是如何创建和启动的、消费者组的多个Consumer会如何分配消息、Consumer会如何从Broker拉取一批消息。
762 11
RocketMQ原理—3.源码设计简单分析下
|
消息中间件 Java 数据管理
RocketMQ原理—2.源码设计简单分析上
本文介绍了NameServer的启动脚本、启动时会解析哪些配置、如何初始化Netty网络服务器、如何启动Netty网络服务器,介绍了Broker启动时是如何初始化配置的、BrokerController的创建以及包含的组件、BrokerController的初始化、启动、Broker如何把自己注册到NameServer上、BrokerOuterAPI是如何发送注册请求的,介绍了NameServer如何处理Broker的注册请求、Broker如何发送定时心跳
|
消息中间件 存储 监控
RabbitMQ如何保证消息可靠性?
RabbitMQ通过多种机制确保消息的可靠性,包括消息持久化、确认机制、消息重试与死信队列、消息去重、高可用性配置以及监控与告警机制。这些措施共同构成了RabbitMQ可靠消息传递的基础,帮助开发者在构建分布式系统时有效避免消息丢失和重复处理问题。理解并正确实施这些技术,将显著提高应用系统的稳定性和用户体验。
1060 14
|
消息中间件 Java 中间件
MQ四兄弟:如何保证消息可靠性
本文介绍了RabbitMQ、RocketMQ、Kafka和Pulsar四种消息中间件的可靠性机制。这些中间件通过以下几种方式确保消息的可靠传输:1. 消息持久化,确保消息在重启后不会丢失;2. 确认机制,保证消息从生产者到消费者都被成功处理;3. 重试机制,处理失败后的重试;4. 死信队列,处理无法消费的消息。每种中间件的具体实现略有不同,但核心思想相似,都是从生产者、中间件本身和消费者三个角度来保障消息的可靠性。
1072 0
|
消息中间件 Arthas Java
RocketMQ—一次连接namesvr失败的案例分析
项目组在使用RocketMQ时遇到Consumer连接Name Server失败的问题,异常显示连接特定地址失败。通过Arthas工具逐步分析代码执行路径,定位到创建Channel返回空值导致异常。进一步跟踪发现,问题源于Netty组件在初始化`ByteBufAllocator`时出现错误。分析依赖后确认存在Netty版本冲突。解决方法为排除冲突的Netty包,仅保留兼容版本。
1445 0
RocketMQ—一次连接namesvr失败的案例分析
|
数据采集 监控 物联网
MQTT协议在智能制造中的应用案例与效益分析
【6月更文挑战第8天】MQTT协议在智能制造中的应用案例与效益分析
866 1
|
消息中间件 存储 运维
深入理解MQ消息队列的高可用与可靠性策略
深入理解MQ消息队列的高可用与可靠性策略
1869 3