RabbitMQ仲裁队列高可用架构解析

#作者:闫乾苓

文章目录

  • 概述
  • 工作原理
    • 1.节点之间的交互
    • 2.消息复制
    • 3.共识机制
    • 4.选举领导者
    • 5.消息持久化
    • 6.自动故障转移
  • 集群环境
  • 节点管理
    • 仲裁队列增加集群节点
    • 重新平衡仲裁队列leader所在节点
    • 仲裁队列减少集群节点
  • 副本管理
    • add_member 在给定节点上添加仲裁队列成员(副本)
    • delete_member删除给定节点上的仲裁队列成员(副本)
  • 节点高可用测试

本文使用目前官方推荐的quorum 类型的队列如何进行高可用设置进行了测试及说明。

概述

仲裁队列是一种现代队列类型,它基于Raft 共识算法实现了持久的、复制的 FIFO 队列。

旨在更加安全,并提供更简单、定义明确的故障处理语义,用户在设计和操作系统时应该更容易推理。

仲裁队列和流现在取代了原始的、复制的镜像经典队列。镜像经典队列早已被弃用,并已从 RabbitMQ 4.x 中删除。

仲裁队列针对数据安全是首要任务的用例进行了优化。仲裁队列应被视为复制队列类型的默认选项。

工作原理

RabbitMQ的仲裁队列通过使用Raft一致性算法、消息复制和持久化等技术,实现了高可用性的消息传输和数据存储。这些机制共同确保了即使在节点故障或网络异常等不利情况下,消息仍然能够可靠地传输和存储

1.节点之间的交互

在RabbitMQ的集群中,节点之间通过交换消息来进行状态同步。当一个新节点加入或发生故障转移时,其他节点会与该节点进行交互,以确保其状态与集群保持同步。

2.消息复制

RabbitMQ使用消息复制技术来确保消息在集群中的可靠存储。每个消息都会被复制到多个节点上,以防止在某些节点发生故障时数据丢失。这种复制机制为数据的高可用性提供了保障。

3.共识机制

RabbitMQ的仲裁队列使用Raft一致性算法来实现共识机制。Raft是一种用于管理复制日志的一致性算法,它通过在集群中的节点之间达成共识来确保消息的可靠传输。当一个节点发送一条消息时,其他节点会验证该消息的一致性,并确保其在整个集群中可靠传输。

4.选举领导者

在RabbitMQ的仲裁队列中,存在一个领导者节点和一个或多个副节点。领导者节点负责处理写请求,而副节点则复制领导者的操作。当领导者节点发生故障时,副节点会通过Raft算法进行选举,以选出一个新的领导者节点来继续处理写请求。

5.消息持久化

RabbitMQ中的仲裁队列支持消息持久化,这意味着即使在节点重启或崩溃的情况下,消息也不会丢失。通过将消息写入磁盘并在副节点之间进行复制,仲裁队列确保了消息的长期保存和可靠性。

6.自动故障转移

如果领导者节点发生故障,RabbitMQ会自动将一个副节点提升为新的领导者节点。其他副节点则会与新的领导者节点进行同步,以确保集群的可用性和数据的一致性。这种自动故障转移机制进一步提高了RabbitMQ仲裁队列的高可用性。

集群环境

Rabbimq集群使用RabbitMQ Cluster Kubernetes Operator部署,使用nfs storageClass的pvc进行持久化存储。

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:name: rabbitmq-cluster01namespace: rabbitmq-test
spec:replicas: 3image: rabbitmq:3.13.7-managementresources:requests:cpu: 500mmemory: 1Gilimits:cpu: 2000mmemory: 4Girabbitmq:additionalConfig: |cluster_partition_handling = pause_minoritydisk_free_limit.relative = 1.0collect_statistics_interval = 10000channel_max = 1000vm_memory_high_watermark_paging_ratio = 0.7total_memory_available_override_value = 4GBlog.file = /var/log/rabbitmq/rabbit.logpersistence:storageClassName: nfsstorage: "20Gi"affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: app.kubernetes.io/nameoperator: Invalues:- rabbitmq-cluster01topologyKey: kubernetes.io/hostnameservice:type: NodePort

节点管理

仲裁队列增加集群节点

通过在指定节点上为所有匹配的队列添加成员(副本)来增长仲裁队列集群。

rabbitmq-queues [--node <node>] [--longnames] [--quiet] grow <node> <all | even> [--vhost-pattern <pattern>] [--queue-pattern <pattern>] [--membership <promotable|voter>]
<--node> 
用于放置副本的节点名称
<all | even> 
为所有匹配的队列或仅为成员计数为偶数的队列添加成员
--queue-pattern 
用于匹配队列名称的正则表达式
--vhost
匹配虚拟主机名的正则表达式
--membership
添加可晋升的非投票人(默认)或正式投票人
--errors-only
仅列出报告错误的队列

为所有匹配的队列,vhost为/,匹配所有queue 增加‘rbt04’副本节点

rabbitmq-queues grow "rabbit@rbt04" "all" --vhost-pattern "/" --queue-pattern ".*"

在这里插入图片描述
在这里插入图片描述
仅为副本数为偶数的队列,vhost为/,匹配所有queue, 增加‘rbt05’副本节点
在这里插入图片描述

[root@rbt01 ~]# rabbitmq-queues grow "rabbit@rbt05" "even" --vhost-pattern "/" --queue-pattern 
".*"

因使用了even参数,只匹配了偶数节点的queue-quorum-02
在这里插入图片描述
在这里插入图片描述

重新平衡仲裁队列leader所在节点

在正在运行的集群节点之间重新平衡复制队列的领导者
用法:

rabbitmq-queues [--node <node>] [--longnames] [--quiet] rebalance < all | classic | quorum | stream > [--vhost-pattern <pattern>] [--queue-pattern <pattern>]
<type>队列类型,必须是以下之一:all、classic、quorum、stream
--queue-pattern <pattern>用于匹配队列名称的正则表达式
--vhost-pattern <pattern>匹配虚拟主机名的正则表达式

在这里插入图片描述
对vhost /下,所有的queue,进行重新平衡leader

[root@rbt01 ~]#  rabbitmq-queues rebalance "all" --vhost-pattern "/" --queue-pattern ".*"

重新平衡后,3个队列的leader 由原来的全部为rbt01,变成了rbt01,rbt03,rbt04
在这里插入图片描述

仲裁队列减少集群节点

用法:

rabbitmq-queues [--node <node>] [--longnames] [--quiet] shrink <node> [--errors-only]
<node>从中删除副本的节点名称
--errors-only仅列出报告错误的队列
[root@rbt01 ~]# rabbitmq-queues shrink rabbit@rbt04
Shrinking quorum queues on rabbit@rbt04...
vhost   name    size    result
/       queue-quorum-03 2       ok
/       queue-quorum-01 4       ok
/       queue-quorum-02 4       ok[root@rbt01 ~]# rabbitmq-queues shrink rabbit@rbt05
Shrinking quorum queues on rabbit@rbt05...
vhost   name    size    result
/       queue-quorum-01 3       ok
/       queue-quorum-02 3       ok

副本管理

声明仲裁队列时,必须在集群中启动其初始副本数。默认情况下,要启动的副本数最多为三个,集群中每个 RabbitMQ 节点一个。
三个节点是仲裁队列的实际最小副本数。在节点数较多的 RabbitMQ 集群中,添加比仲裁更多的副本不会在仲裁队列可用性方面带来任何改进,但会消耗更多集群资源。
因此,仲裁队列的推荐副本数是群集节点的仲裁数(但不少于三个)。这假设一个完整的群集至少有三个节点。

仲裁队列的副本由管理员管理。当新节点添加到集群时,它将不托管仲裁队列副本,除非管理员明确将其添加到仲裁队列或仲裁队列集的成员(副本)列表中。
当需要退役节点(从集群中永久删除)时,必须将其从其当前托管副本的所有仲裁队列的成员列表中明确删除。
为了成功添加和删除成员,集群中必须有一定数量的副本,因为集群成员资格的更改被视为队列状态的更改。
在执行涉及成员资格变更的维护操作时,需要小心不要因失去法定人数而意外导致队列不可用。
更换集群节点时,先添加新节点然后再退役其替换的节点是更安全的做法。

用于队列(尤其是仲裁队列)的维护任务, 管理复制队列的副本

add_member 在给定节点上添加仲裁队列成员(副本)

在这里插入图片描述

rabbitmq-queues add_member --vhost / queue-quorum-01 rabbit@rbt04
rabbitmq-queues add_member --vhost / queue-quorum-01 rabbit@rbt05

在这里插入图片描述

delete_member删除给定节点上的仲裁队列成员(副本)

rabbitmq-queues delete_member --vhost / queue-quorum-01 rabbit@rbt01
rabbitmq-queues delete_member --vhost / queue-quorum-01 rabbit@rbt02

在这里插入图片描述

节点高可用测试

创建queue

rabbitmqadmin declare queue name=queue_quorum_01 durable=true arguments='{"x-queue-type": "quorum"}'

创建exchange及bingding

rabbitmqadmin  declare exchange name=exchange_quorum_01 type=direct durable=true
rabbitmqadmin declare binding source=exchange_quorum_01 destination=queue_quorum_01 routing_key=queue_quorum_01

查看创建的queue_quorum_01的状态
在这里插入图片描述
查看exchange是否创建成功
在这里插入图片描述
通过python脚本写入10000条消息数据。
在这里插入图片描述
手动删除1个pod节点,模拟3节点集群中1个节点宕机的故障,数据不会丢失。
在这里插入图片描述
继续在producer客户端和cunsume 客户端python脚本一直时运行时,进行删除pod节点测试。
在这里插入图片描述
只要客户端连接的不是被停止的pod节点,客户端生产和消费都是正常的。通过web管理界面看,队列的状态是:running
在这里插入图片描述
此时如果继续删除第2个pod节点,模拟3节点集群中2个节点宕机的故障,在k8s中使用operator部署的RabbitMQ集群,在手动执行删除第2个pod是,命令将被挂起(无反应)直到operator通过内容部控制机制将第1个删除的pod重启成功,才会继续执行第2个pod的删除操作。
此时Rabbimq服务是正常状态(如果客户端连接的是被删除pod节点,连接会被断开,重连后连接被svc 负载到其他pod节点,可以正常读写数据)。这应该是RabbitMQ operator控制的效果,在3节点的集群中,确保同时只能1个pod节点宕机,服务不受影响。
在这里插入图片描述
在此期间,消息队列中的数据不会丢失。

另外在裸金属部署的3节点RabbitMQ集群中进行了类似测试,使用“rabbitmq stop_app”同时停止2个节点(非读写客户端正在连接的节点),此时RabbitMQ处于“minority”(少数)状态,这正是quorum队列需要超过半数节点正常才能正常工作的工作机制。
在这里插入图片描述
此时,写客户端(producer)的连接状态虽然为‘running’但实际测试是没有数据写入到服务器,读客户端(consumer)的连接状态为“flow”,也不能从服务器获取数据。
在这里插入图片描述

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

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

相关文章

fingerprint2浏览器指纹使用记录

我在uniapp-vue3-H5端使用的&#xff0c;记录一下 抄的这里前端使用fingerprintjs2获取浏览器指纹fingerprintjs2是通过设备浏览器信息获取浏览器指纹的插件&#xff08; - 掘金 1、安装依赖 npm i fingerprintjs2 -S2、抽成模块文件&#xff0c;/utils/Fingerprint2.js 生成指…

深度学习面试八股简略速览

在准备深度学习面试时&#xff0c;你可能会感到有些不知所措。毕竟&#xff0c;深度学习是一个庞大且不断发展的领域&#xff0c;涉及众多复杂的技术和概念。但别担心&#xff0c;本文将为你提供一份全面的指南&#xff0c;从基础理论到实际应用&#xff0c;帮助你在面试中脱颖…

使用 Redis 作为向量数据库

一、什么是向量数据库&#xff1f; 向量&#xff08;Vector&#xff09;&#xff1a;在机器学习和 AI 中&#xff0c;向量是由一系列数字组成的序列&#xff0c;用于数值化地描述数据的特征或语义。文本、图像、音频等非结构化数据可以通过模型转换成固定长度的向量。 向量数据…

变量的计算

不同类型变量之间的计算 数字型变量可以直接计算 在python中&#xff0c;数字型变量可以直接通过算术运算符计算bool型变量&#xff1a;True 对应数字1 &#xff1b;False 对应数字0、 字符串变量 使用 拼接字符串 使用 * 拼接指定倍数的相同字符串 变量的输入&#xff1a;&…

PostgreSQL学会如何建表

开始使用PostgreSQL之前&#xff0c; 上一节我们说了怎样安装它。 PostgreSQL可能已经安装到你的电脑上了,安装后postgre服务默认在电脑开机时运行启动。 一.了解PostgreSQL的运行 PostgreSQL使用一种客户端/服务器&#xff08;C/S&#xff09;模型。 和其他典型的客户端/服务…

Linux驱动学习笔记(十)

热插拔 1.热插拔&#xff1a;就是带电插拔&#xff0c;即允许用户在不关闭系统&#xff0c;不切断电源的情况下拆卸或安装硬盘&#xff0c;板卡等设备。热插拔是内核和用户空间之间&#xff0c;通过调用用户空间程序实现交互来实现的&#xff0c;当内核发生了某种热拔插事件时…

大模型应用开发第五讲:成熟度模型:从ChatGPT(L2)到未来自主Agent(L4)

大模型应用开发第五讲&#xff1a;成熟度模型&#xff1a;从ChatGPT&#xff08;L2&#xff09;到未来自主Agent&#xff08;L4&#xff09; 资料取自《大模型应用开发&#xff1a;动手做AI Agent 》。 查看总目录&#xff1a;学习大纲 关于DeepSeek本地部署指南可以看下我之…

Delphi 导入excel

Delphi导入Excel的常见方法可分为两种主流方案&#xff1a;基于OLE自动化操作Excel原生接口和利用第三方组件库。以下为具体实现流程及注意事项&#xff1a; ‌一、OLE自动化方案&#xff08;推荐基础场景&#xff09;‌ 该方法通过COM接口调用本地安装的Excel程序&#xff0c…

Selenium的第四天打卡——Selenium浏览器应用(完整版)

Selenium浏览器应用 目录 Selenium浏览器应用 一、浏览器操作示例代码 1.设置浏览器缩放大小 2.浏览器前进和后退 3.浏览器刷新 二、WebDriver常见方法 三、鼠标事件示例 四、键盘事件示例 五、获取断言信息 六、窗口的切换 七、关键注意事项 一、浏览器操作示例代…

PMO价值重构:从项目管理“交付机器”到“战略推手”

在数字化转型浪潮中&#xff0c;项目管理办公室&#xff08;PMO&#xff09;正经历着前所未有的角色蜕变。传统上&#xff0c;PMO往往被视为项目管理的“交付机器”&#xff0c;专注于项目的按时交付和资源分配。然而&#xff0c;随着企业对战略执行的重视&#xff0c;PMO正逐渐…

本地依赖库的版本和库依赖的版本不一致如何解决?

我用的 yarn v4 版本&#xff0c;所以以下教程命令都基于yarn 这里假设我报错的库名字叫 XXXXXXXX&#xff0c;依赖他的库叫 AAAAAAAA 排查解决思路分析&#xff1a; 首先查看一下 XXXXXXXX 的依赖关系&#xff0c;执行 yarn why XXXXXXXX 首先我们要知道 yarn 自动做了库…

SQLiteStudio - 免费开源、轻量高效,跨平台的 SQLite 数据库管理工具,代替 Navicat for SQLite

管理 SQLite 数据库就用这款软件&#xff0c;真的早该摒弃破解和盗版的 Navicat 了。 SQLiteStudio 是一款专注于管理 SQLite 数据库 的桌面软件&#xff0c;用于浏览和编辑 SQLite 数据库文件。软件的作者是来自波兰的开发者 Paweł Salawa&#xff0c;他是一位拥有 20 年 Ja…

DeepSeek R1-0528 新开源推理模型(免费且快速)

DeepSeek推出了新模型,但这不是R2! R1-0528是DeepSeek的最新模型,在发布仅数小时后就在开源社区获得了巨大关注。 这个悄然发布的模型DeepSeek R1-0528,已经开始与OpenAI的o3一较高下。 让我来详细介绍这次更新的新内容。 DeepSeek R1-0528 发布 DeepSeek在这次发布中采…

Opera Neon发布该公司首款“AI代理”浏览器

Opera 的浏览器产品组合今日迎来了新成员。Opera Neon 是该公司首款“AI 代理”浏览器&#xff0c;旨在“重新思考浏览器在代理网络中的角色”。开发人员声称&#xff0c;Neon 能够理解用户的意图&#xff0c;并利用 AI 驱动的功能将其转化为行动。 Opera Neon 由三个主要部分…

网络安全之Web渗透加解密

项目基本使用 准备环境&#xff1a;node.js python chrome npm install chrome-remote-interface pip install playwright playwright install chromium pip install mitmproxy ............... 第一步启动cdp.js。 第二步使用python .\cdp_load.py vue_demo&#xff0c;连…

【VSCode-Qt】Docker远程连接的项目UI文件在 VSCode 上无法预览

Docker远程连接的UI文件在 VSCode 上无法预览&#xff0c;通常是因为 VSCode 通过远程开发扩展&#xff08;Remote - SSH/Docker&#xff09;连接到 Docker 容器时&#xff0c;某些图形化功能未正确配置或支持。以下是可能原因和解决方案&#xff1a; 原因分析 X11 转发未配置…

【HW系列】—web组件漏洞(Strtus2和Apache Log4j2)

本文仅用于技术研究&#xff0c;禁止用于非法用途。 文章目录 Struts2Struts2 框架介绍Struts2 历史漏洞汇总&#xff08;表格&#xff09;Struts2-045 漏洞详解 Log4j2Log4j2 框架介绍Log4j2 漏洞原理1. JNDI 注入2. 利用过程 Log4j2 历史漏洞JNDILDAP 反弹 Shell 流程 Strut…

《深度关系-从建立关系到彼此信任》

陈海贤老师推荐的书&#xff0c;花了几个小时&#xff0c;感觉现在的人与人之间特别缺乏这种深度的关系&#xff0c;但是与一个人建立深度的关系并没有那么简单&#xff0c;反正至今为止&#xff0c;自己好像没有与任何一个人建立了这种深度的关系&#xff0c;那种双方高度同频…

sass基础语法

Sass&#xff08;Syntactically Awesome Style Sheets&#xff09;是一种 CSS 预处理器&#xff0c;提供了比原生 CSS 更强大、更灵活的语法功能。它有两种语法格式&#xff1a; Sass&#xff08;缩进语法&#xff0c;.sass 文件&#xff09;SCSS&#xff08;CSS-like 语法&am…

【JavaWeb】基本概念、web服务器、Tomcat、HTTP协议

目录 1. 基本概念1.1 基本概念1.2 web应用程序1.3 静态web1.4 动态web 2. web服务器3. tomcat详解3.1 安装3.2 启动3.3 配置3.3.1 配置启动的端口号3.3.2 配置主机的名称3.3.3 其他常用配置项日志配置数据源配置安全配置 3.4 发布一个网站 4. Http协议4.1 什么是http4.2 http的…