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
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85001.shtml
英文地址,請注明出處:http://en.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的…