聊聊RabbitMQ(三)RabbitMQ的集群与运维

本文深入探讨RabbitMQ的集群方案,包括单机多实例部署、主备模式、镜像队列、Shovel插件、Federation联邦模式。重点讲解了镜像队列的高可用性,如何通过HAProxy实现负载均衡,并介绍了监控与集群管理策略。同时,提到了RabbitMQ集群中常见的问题和解决方案。
摘要由CSDN通过智能技术生成

集群方案原理

对于无状态应用(如普通的微服务)很容易实现负载均衡、高可用集群。而对于有状态的系统(如数据库等)就比较复杂。

  1. 业界实践:
  • 主备模式:单活,容量对等,可以实现故障转移。使用独立存储时需要借助复制、镜像同步等技术,数据会有延迟、不一致等问题(CAP定律),使用共享存储时就不会有状态同步这个问题。
  • 主从模式:一定程度的双活,容量对等,最常见的是读写分离。通常也需要借助复制技术,或者要求上游实现双写来保证节点数据一致。
  • 主主模式:两边都可以读写,互为主备。如果两边同时写入很容易冲突,所以通常实现的都是“伪主主模式”,或者说就是主从模式的升级版,只是新增了主从节点的选举和切换。
  • 分片集群:不同节点保存不同的数据,上游应用或者代理节点做路由,突破存储容量限制,分摊读写负载;典型的如MongoDB的分片、MySQL的分库分表、Redis集群。
  • 异地多活:“两地三中心”是金融行业经典的容灾模式(有资源闲置的问题),“异地多活”才是王道。
  1. 常用负载均衡算法:
    1. 随机
    2. 轮询
    3. 加权轮询
    4. 最少活跃连接
    5. 原地址/目标地址hash(一致性hash)
  2. 集群中的经典问题:
    脑裂(可以通过协调器选举算法、仲裁节点等方式来解决)
    网络分区、一致性、可用性(CAP)
    相关景点的技术和工具:LVS、HAProxy、Nginx、KeepAlived、Heartbeat、DRBD、Corosync、Pacemaker、MMM/MHA、Galera、MGR等,感兴趣的同学可以研究。
    现在太多公司选择直接购买公有云服务,基本不用太关心很多基础设施和中间件的部署、运维细节。但是这些技术以及背后的原理是非常重要的。
  3. RabbitMQ分布式架构模式
  • 主备模式
    也叫Warren(兔子窝)模式,同一时刻只有一个节点在工作(备份节点不能读写),当主节点发生故障后会将请求切换到备份节点上(主恢复后成为备份节点)。需要借助HAProxy之类的(VIP模式)负载均衡器来做健康检查和主备切换,底层需要借助共享存储(如SAN设备)。
    这不是RabbitMQ官方或者开源社区推荐方案,适用于访问压力不是特别大但是又有高可用架构需求(故障切换)的中小规模的系统来使用。首先有一个节点闲置,本身就是资源浪费,其次共享存储往往需要借助硬件存储,或者分布式文件系统。
    在这里插入图片描述
  • Shovel铲子模式
    Shovel是一个插件,用于实现跨机房数据复制,或者数据迁移,故障转移与恢复等。
    如下图,用户下单的消费先是投递在Goleta Broker实例中,当Goleta实例达到触发条件后(例如:消息堆积数达到阈值)会将消息放到Goleta实例的backup_orders备份队列中,并通过Shovel插件从Goleta的backup_orders队列中将消息拉取到Carpinteria实例存储。
    在这里插入图片描述
    在这里插入图片描述
    使用Shovel插件后,模型变成了近端同步确认,远端异步确认的方式。
    此模式支持WAN传输,并且broker实例的RabbitMQ、Erlang版本不要求完全一致。
    Shovel的配置分静态模式(修改RabbitMQ配置)和动态模式(在控制台直接部署,重启后失效)
  • RabbitMQ集群
    RabbitMQ集群允许消费者和生产者在RabbitMQ单个节点崩溃的情况下继续运行,并可以通过添加更多的节点来线性扩展消息通信的吞吐量。当失去一个RabbitMQ节点时,客户端能够重新连接到集群中的任何其他节点并继续生产和消费。
    RabbitMQ集群中的所有节点都会备份所有的元数据信息,包括:
    1. 队列元数据:队列的名称及属性;
    2. 交换器:交换器的名称及属性;
    3. 绑定关系元数据:交换器与队列或者交换器与交换器之间的绑定关系;
    4. vhost元数据:为vhost内的队列、交换器和绑定提供命名空间及安全属性。

基于存储空间和性能的考虑,RabbitMQ集群中的各节点存储的消息是不同的(有点儿类似分片集群,各节点数据并不是全量对等的),各节点之间同步备份的仅仅是上述元数据以及Queue Owner(队列所有者,就是实际创建Queue并保存消息数据的节点)的指针。当集群中某个节点崩溃后,该节点的队列进程和关联的绑定都会消失,关联的消费者也会丢失订阅信息,节点恢复后(前提是消息有持久化)消息可以重新被消费。虽然消息本身也会持久化,但如果节点磁盘存储设备发生故障那同样会导致消息丢失。

总的来说,该集群模式只能保证集群中的某个Node挂掉后应用程序还可以切换到其他Node上继续
地发送和消费消息,但并无法保证原有的消息不丢失,所以并不是一个真正意义的高可用集群。
在这里插入图片描述
这是RabbitMQ内置的集群模式,Erlang语言天生具备分布式特性,所以不需要借助类似Zookeeper之类的组件来实现集群(集群节点间使用cookie来进行通信验证,所有节点都必须使用相同的 .erlang.cookie 文件内容),不同节点的Erlang、RabbitMQ版本必须一致。

  • 镜像队列模式
    RabbitMQ内置的集群模式有丢失消息的风险,“镜像队列”可以看成是对内置默认集群模式的一种高可用架构的补充。可以将队列镜像(同步)到集群中的其他broker上,相当于是多副本冗余。如果集群中的一个节点失效,队列能自动地切换到集群中的另一个镜像节点上以保证服务的可用性,而且消息不丢失。
    在RabbitMQ镜像队列中所谓的master和slave都仅仅是针对某个queue而言的,而不是node。一个queue第一次创建所在的节点是它的master节点,其他节点为slave节点。如果master由于某种原因失效,最先加入的slave会被提升为新的master。
    无论客户端请求到达master还是slave,最终数据都是从master节点获取。当请求到达master节点时,master节点直接将消息返回给client,同时master节点会通过GM(Guaranteed Multicast)协议将queue的最新状态广播到slave节点。GM保证了广播消息的原子性,即要么都更新要么都不更新。当请求到达slave节点时,slave节点需要将请求先重定向到master节点,master节点将消息返回给client,同时master节点会通过GM协议将queue的最新状态广播到slave节点。
    很多同学可能就会疑惑,这样设计太傻叉了,slave完全是闲置的啊!干嘛不学习MySQL主从复制,起码可以搞个读写分离啊!其实业界很多HA架构实践中冗余资源都是闲置的。前面我们讲了RabbitMQ镜像队列中的master、slave是Queue维度而并非Node维度,所以我们可以交叉减少资源限制,如下图所示:
    在这里插入图片描述
  • Federation联邦模式
    Federation和Shovel类似,也是一个实现跨集群、节点消息同步的插件。支持联邦交换器、联邦队列(作用在不同级别)。
    Federation插件允许你配置一个exchanges federation或者queues federation。
    一个exchange/queues federation允许你从一个或者多个upstream接收信息,就是远程的exchange/queues。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值