RabbitMQ之集群方案原理

news2024/9/27 23:25:08

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

1、业界实践

  • 主备模式:单活,容量对等,可以实现故障转移。使用独立存储时需要借助复制、镜像同步等技术,数据会有延迟、不一致等问题(CAP定律),使用共享存储时就不会有状态同步这个问题。
  • 主从模式:一定程度的双活,容量对等,最常见的是读写分离。通常也需要借助复制技术,或者要求上游实现双写来保证节点数据一致。
  • 主主模式:两边都可以读写,互为主备。如果两边同时写入很容易冲突,所以通常实现的都是“伪主主模式”,或者说就是主从模式的升级版,只是新增了主从节点的选举和切换。
  • 分片集群:不同节点保存不同的数据,上游应用或者代理节点做路由,突破存储容量限制,分摊读写负载;典型的如MongoDB的分片、MySQL的分库分表、Redis集群。
  • 异地多活:“两地三中心”是金融行业经典的容灾模式(有资源闲置的问题),“异地多活”才是王道。

2、常用负载均衡算法:

  1. 随机
  2. 轮询
  3. 加权轮询
  4. 最少活跃连接
  5. 原地址/目标地址hash(一致性hash)

3、集群中的经典问题:

脑裂(可以通过协调器选举算法、仲裁节点等方式来解决)

网络分区、一致性、可用性(CAP)

        相关技术和工具:LVS、HAProxy、Nginx、KeepAlived、Heartbeat、DRBD、Corosync、Pacemaker、MMM/MHA、Galera、MGR等,感兴趣的同学可以研究。

        现在太多公司选择直接购买公有云服务,基本不用太关心很多基础设施和中间件的部署、运维细节。但是这些技术以及背后的原理是非常重要的。

4、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。

        无论是Federation还是Shovel都只是解决消息数据传输的问题(当然插件自身可能会一些应用层的优化),跨机房跨城市的这种网络延迟问题是客观存在的,不是简单的通过什么插件可以解决的,一般需要借助昂贵的专线。 

        很多书籍和文章中存在误导大家的,可能会说Federation/Shovel可以解决延迟的问题,可以实现异地多活等等,其实这都是错误的。而且我可以负责人的告诉大家,他们所谓的“异地多活”并非大厂最佳实践。

        例如:使用Shovel构建集群,RabbitMQ和应用程序都选择双机房部署时,当杭州机房发生了消息积压后超出阈值部分的消息就会被转发到上海机房中,此时上海机房的应用程序直接消费掉上海机房RabbitMQ的消息,这样看起来上海机房是可以分摊负载,而且一定程度上实现“双机房多活”的。但是数据库呢?选择两边都部署还是仅部署在某个机房呢?两边同时写入是很容易造成冲突的,如果数据库仅仅部署在杭州机房,那么数据库也可能成为瓶颈导致消费速度依然上不去,只不过是多了上海机房中的消费者实例节点而已。

        而使用Federation模式呢?如果要真正要实现“双机房多活”那么应用程序也是多机房的,那某些Exchange/Queue中的消息会在两边机房都有,两边机房的应用程序都会同时消息,那必然会造成重复消息!

异地多活架构

方案容量容灾成本
异地多活[优]基于逻辑机房,容量可伸缩的云微架构
[优]容量可异地伸缩
[优]日常运行,容灾时可用性高。
[劣]受城际网络故障影响,影响度取决于横向依赖程度
[优]IDC、应用等成本在日常得到有效利用
两地三中心[劣]仅可部署在一个城市,容量伸缩有城市级瓶颈[劣]灾备设施冷备等待,容灾时可用性低。[劣]容灾设施等成本仅在容灾时才使用,且受限于可用性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/56031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Matplotlib绘制图像大全】(二十五):Matplotlib使用figure()添加画布

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

2022re:Invent:亚马逊云科技拥有超过15年的数据创新经验

在探索适合企业的数据战略的道路上,企业并不孤单。亚马逊云科技有着超过15年的数据领域创新经验。并一直在尝试通过创新的方法去改进数据存储和分析的过程:亚马逊云科技在云中提供了第一个可扩展存储服务S3、发布了云上第一个专门构建的数据库DynamoDB和…

easyrecovery2023免费版电脑数据恢复软件下载功能介绍

误删了重要文件?电脑中毒数据丢失?本想拷贝却手抖格式化了?那可以试试easyrecovery,这是一款十分强大的电脑数据恢复软件,界面简洁明了,操作也是十分的简单,只需要根据文字提示来进行操作即可进…

B端产品实战课读书笔记:第七章B端产品常用功能设计

目录 一、工作台 二、列表 三、搜索/筛选 3.1输入框搜索 3.2 单选/复选筛选 3.3 独立/联动筛选 3.4 其他 四、审批 4.1概念 4.2扩展功能 4.3设计要点 五、用户--角色--权限 5.1 什么是RBAC模型 5.2单系统的用户权限设计 5.3多系统的用户权限设计 六、可视化 6.…

用HTML+CSS做一个漂亮简单的音乐网站

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

[附源码]计算机毕业设计springboot新能源汽车租赁

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

基于STM32G431嵌入式学习笔记——九、IIC总线(一)EEPROM

一、基础原理剖析 先前的实验中我们都是通过程序设计语言去调用串口、定时器、引脚等硬件设备进行从0到有的功能实现,所有的指令以及数据均来自程序设计语言,而没有想计算机一样将一些必要数据存入存储器中。 IIC总线是我们嵌入式板子上进行数据传输的主…

太简单了,一文彻底搞懂Jenkins的用法

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 你想要的,这里都有! 我在前公司的某个部门做过一年CV算法工程师,部门推崇全栈式开发。换句话说,做算法,不能只聚焦于算法,要全流…

阿里云NAS存储部署简介

近期在阿里云上部署OCP需要用到NAS,其中遇到NAS无法扩容的问题,在此简单笔记。 1、部署NAS 参照github.com\kubernetes-sigs\alibaba-cloud-csi-driver\docs\nas.md部署说明,需要执行以下步骤: Step 1: Create RBAC resource …

四、伊森商城 前端基础-Vue MVVM思想Vue安装单向绑定 p21

目录 一、MVVM 思想 二、Vue 简介 2.1、安装 2.1.1、初始化vue项目 -y默认确定 2.1.2、安装上vue的2.6.11版本 三、Vue的单向绑定 一、MVVM 思想 M:即 Model,模型,包括数据和一些基本操作 V:即 View,视图&#xf…

【Docker】常用命令总结

Docker是基于Go语言实现的云开源项目。Docker的主要目标是**“Build,Ship and Run Any App,Anywhere”**。也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运…

容器开发运维人员的 Linux 操作机配置优化建议

"工欲善其事必先利其器", 作为一个PAAS平台架构师, 容器相关技术(docker, k8s等)是必不可少的. 本文简单介绍下我自己的Linux操作机配置. 提升工作效率, 提高使用体验. :heart::heart::heart: :exclamation: 注意: 本文以CentOS 7.6 为例, RHEL7.6 操作类似. Ubuntu系…

为什么简历上不要轻易写“精通分布式”,一线大厂为什么面试必问分布式?

为什么要学习分布式? 作为一名后端 Java 程序员,我们在找工作写简历的时候除了高并发经验。一般情况下都还会写上自己熟悉/了解/掌握/精通分布式系统,所以高并发和分布式大多是成对出现的。 在某直聘网站上搜到的 Java 岗位 这么多金的一个知…

Shiro-SpringBoot (二)

在上一节中实现了在SpringBoot中使用Shiro做权限控制,但是针对上一节留下的不足点,在这里进行一下优化和改造,主要有一下几点: 支持AJAX请求支持FreeMarker模板URL拦截提取到yml配置文件 (一) 支持AJAX请求 如果是AJAX请求URL接口&#xff0…

软件外包公司真的去不得吗?

各位小伙伴们!好!啊!最近全国大部分地区都降温了,大家记得做好保暖,不要生病。 无论是应届毕业生,还是准备跳槽的测试人,都有面对“软件外包”公司的可能。有些人说进入外包公司就相当于给履历…

电子招标采购商城系统:优化传统采购业务,提速企业数字化升级

后疫情时代,电子元器件供应链发生了巨大的变化,缺货已经影响了大多数企业,电子元器件采购人员每天被“缺货”“涨价”的字眼包围着,对电子元器件企业的发展带来了极大的限制。当前,借助数字化技术对电子元器件采购管理…

[附源码]计算机毕业设计在线票务系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

云服务器和本地服务器的优缺点分析

服务器是企业IT基础设施的命脉,可用于存放文件、应用程序、网站、员工远程访问等等。当然,选择时有许多不同类型的服务器和许多需要考虑的因素。目前比较流行的两种服务器类型是本地服务器和基于云的服务器。 本地服务器 本地服务器放置在公司的办公室中…

VS2022开发Arduino(90%转载10%原创)

先上转载链接 VS2022开发Arduino(提供Visual.Micro.Processing.Sketch.dll)_hb2cpc的博客-CSDN博客_vs开发arduino Visual Studio 2022开发Arduino详述_liht_1634的博客-CSDN博客_visualstudio arduino 其中破解部分编译出错,此处为原创&am…

RabbitMQ面试篇

文章目录1 你们为什么选择了RabbitMQ而不是其它的MQ?2 RabbitMQ如何确保消息的不丢失?3 RabbitMQ如何避免消息堆积?4 RabbitMQ如何保证消息的有序性?5 如何防止MQ消息被重复消费?6 如何保证RabbitMQ的高可用&#xff1…