首頁 後端開發 php教程 如何保證訊息佇列的高可用?

如何保證訊息佇列的高可用?

Jan 28, 2020 pm 01:28 PM
訊息佇列

訊息佇列在高並發的場景是必備技能,隨著我們的使用,在生產環境中的問題也是非常的多,例如:訊息佇列如何做到高可用呢?

場景的中間件有很多種類型,在這裡就準備常用的一些就用於分析處理。

1. RabbitMQ 的高可用性

RabbitMQ 是比較有代表性的,因為是基於主從(非分散式)做高可用性的,我們就以RabbitMQ 為例子說明第一種MQ 的高可用性怎麼實現。

RabbitMQ 有三種模式:單機模式、普通叢集模式、鏡像叢集模式。

單機模式

單機模式,就是 Demo 等級的,通常就是你本地啟動了玩玩兒的,沒人生產用單機模式。

普通叢集模式(無高可用性)

普通叢集模式,意思是在多台機器上啟動多個 RabbitMQ 實例,每個機器啟動一個。你創建的 queue,只會放在一個 RabbitMQ 實例上,但是每個實例都同步 queue 的元數據(元數據可以認為是 queue 的一些配置信息,透過元數據,可以找到 queue 所在實例)。

你消費的時候,實際上如果連接到了另一個實例,那麼那個實例會從 queue 所在實例上拉取資料過來。

 如何保證訊息佇列的高可用?

 

這種方式確實很麻煩,也不怎麼好,沒做到所謂的分散式,就是個普通叢集。因為這導致你要麼消費者每次隨機連接一個實例然後拉取數據,要麼固定連接那個 queue 所在實例消費數據,前者有數據拉取的開銷,後者導致單實例效能瓶頸。

而且如果那個放queue 的實例宕機了,會導致接下來其他實例就無法從那個實例拉取,如果你開啟了訊息持久化,讓RabbitMQ 落地儲存訊息的話,訊息不一定會丟,得等這個實例恢復了,然後才可以繼續從這個queue 拉取資料。

所以這個事兒就比較尷尬了,這就沒有什麼所謂的高可用性,這方案主要是提高吞吐量的,就是說讓集群中多個節點來服務某個queue 的讀寫操作。

鏡像叢集模式(高可用性)

這個模式,才是所謂的 RabbitMQ 的高可用模式。跟普通叢集模式不一樣的是,在鏡像叢集模式下,你所建立的queue,無論元資料或queue 裡的訊息都會存在於多個實例上,就是說,每個RabbitMQ 節點都有這個queue 的一個完整鏡像,包含queue 的全部資料的意思。然後每次你寫訊息到 queue 的時候,都會自動把訊息同步到多個實例的 queue 上。

 如何保證訊息佇列的高可用?

 

那麼如何開啟這個鏡像叢集模式呢?其實很簡單,RabbitMQ 有很好的管理控制台,就是在後台新增一個策略,這個策略是鏡像叢集模式的策略,指定的時候是可以要求資料同步到所有節點的,也可以要求同步到指定數量的節點,再次創建queue 的時候,應用這個策略,就會自動將資料同步到其他的節點上去了。

這樣的話,好處在於,你任何一個機器宕機了,沒事,其它機器(節點)還包含了這個 queue 的完整數據,別的 consumer 都可以到其它節點上去消費數據。

壞處在於,第一,這個效能開銷也太大了吧,訊息需要同步到所有機器上,導致網路頻寬壓力和消耗很重!

第二,這些玩兒,不是分散式的,就沒有擴展性可言了,如果某個queue 負載很重,你加機器,新增的機器也包含了這個queue 的所有數據,並沒有辦法線性擴展你的queue。

2. Kafka 的高可用性

Kafka 一個最基本的架構認識:由多個broker 組成,每個broker 是一個節點;你創建一個topic,這個topic 可以分割成多個partition,每個partition 可以存在於不同的broker 上,每個partition 就放一部分資料。

這就是天然的分散式訊息佇列,就是說一個 topic 的數據,是分散放在多個機器上的,每個機器就放一部分資料。

實際上RabbmitMQ 之類的,並不是分散式訊息佇列,它就是傳統的訊息佇列,只不過提供了一些叢集、HA(High Availability, 高可用性) 的機製而已,因為無論怎麼玩兒,RabbitMQ 一個queue 的資料都是放在一個節點裡的,鏡像叢集下,也是每個節點都放這個queue 的完整資料。

Kafka 0.8 以前,是沒有 HA 機制的,就是任何一個 broker 宕機了,那個 broker 上的 partition 就廢了,沒法寫也沒法讀,沒有什麼高可用性可言。

比如說,我們假設建立了一個 topic,指定其 partition 數量是 3 個,分別在三台機器上。但是,如果第二台機器宕機了,會導致這個 topic 的 1/3 的資料就丟了,因此這個是做不到高可用的。

 

如何保證訊息佇列的高可用?

 

Kafka 0.8 以後,提供了 HA 機制,也就是 replica(複製品) 複製機制。每個 partition 的資料都會同步到其它機器上,形成自己的多個 replica 副本。所有 replica 會選出一個 leader 出來,那么生產和消費都跟這個 leader 打交道,然後其他 replica 就是 follower。寫的時候,leader 會負責把資料同步到所有 follower 上去,讀的時候就直接讀 leader 上的資料即可。只能讀寫 leader?

很簡單,如果你可以隨意讀寫每個 follower,那麼就要 care 資料一致性的問題,系統複雜度太高,很容易出問題。 Kafka 會均勻地將一個 partition 的所有 replica 分佈在不同的機器上,這樣才可以提高容錯性。

 

如何保證訊息佇列的高可用?

 

這麼搞,就有所謂的高可用性了,因為如果某個broker 宕機了,沒事,那個broker上面的partition 在其他機器上都有副本的。如果這個宕機的 broker 上面有某個 partition 的 leader,那麼此時會從 follower 中重新選舉一個新的 leader 出來,大家繼續讀寫那個新的 leader 即可。這就有所謂的高可用性了。

寫資料的時候,生產者就寫 leader,然後 leader 將資料落地寫本機磁碟,接著其他 follower 自己主動從 leader 來 pull 資料。一旦所有 follower 同步好資料了,就會發送 ack 給 leader,leader 收到所有 follower 的 ack 之後,就會傳回寫成功的訊息給生產者。 (當然,這只是其中一種模式,還可以適當調整這個行為)

消費的時候,只會從leader 去讀,但是只有當一個訊息已經被所有follower 都同步成功返回ack 的時候,這個消息才會被消費者讀到。

更多相關php知識,請造訪php教學

以上是如何保證訊息佇列的高可用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java Websocket開發實戰:如何實作訊息佇列功能 Java Websocket開發實戰:如何實作訊息佇列功能 Dec 02, 2023 pm 01:57 PM

JavaWebsocket開發實戰:如何實現訊息佇列功能引言:隨著網路的快速發展,即時通訊變得越來越重要。在許多網路應用程式中,需要透過即時訊息傳遞來實現即時更新和通知功能。 JavaWebsocket是一種在Web應用程式中實現即時通訊的技術。本文將介紹如何利用JavaWebsocket來實作訊息佇列功能,並提供具體的程式碼範例。訊息佇列的基本概念消

如何在FastAPI中使用訊息佇列進行非同步任務處理 如何在FastAPI中使用訊息佇列進行非同步任務處理 Jul 30, 2023 pm 09:21 PM

如何在FastAPI中使用訊息佇列進行非同步任務處理引言:在網路應用程式中,經常會遇到需要處理耗時的任務,例如傳送電子郵件、產生報表等。如果將這些任務放在同步的請求-回應流程中,會導致使用者需要等待較長時間,降低使用者體驗和伺服器的回應速度。為了解決這個問題,我們可以使用訊息佇列來進行非同步任務處理。本文將介紹如何在FastAPI框架中使用訊息佇列進行非同步任務的處

Golang開發:使用NATS建構可靠的訊息佇列 Golang開發:使用NATS建構可靠的訊息佇列 Sep 21, 2023 am 11:21 AM

Golang開發:使用NATS建立可靠的訊息佇列,需要具體程式碼範例引言:在現代分散式系統中,訊息佇列是一個重要的元件,用於處理非同步通訊、解耦系統元件和實作可靠的訊息傳遞。本文將介紹如何使用Golang程式語言和NATS(全名為"高效能可靠訊息系統")來建立一個高效、可靠的訊息佇列,並提供具體的程式碼範例。什麼是NATS? NATS是一種輕量級的、開源的訊息系統。

Redis在訊息佇列中的妙用 Redis在訊息佇列中的妙用 Nov 07, 2023 pm 04:26 PM

Redis在訊息佇列中的妙用訊息佇列是一種常見的解耦架構,用於在應用程式之間傳遞非同步訊息。透過將訊息傳送到佇列中,發送者可以在不等待接收者回應的情況下繼續執行其他任務。而接收者可以在適當的時間從隊列中獲取訊息並進行處理。 Redis是一種常用的開源記憶體資料庫,具備高效能和持久性儲存的能力。在訊息佇列中,Redis的多種資料結構和優秀的效能使其成為一個理想的選擇

C#開發中如何處理分散式事務和訊息佇列 C#開發中如何處理分散式事務和訊息佇列 Oct 09, 2023 am 11:36 AM

C#開發中如何處理分散式事務和訊息佇列引言:在今天的分散式系統中,事務和訊息佇列是非常重要的元件。在處理資料一致性和系統解耦方面,分散式事務和訊息佇列起著至關重要的作用。本文將介紹如何在C#開發中處理分散式事務和訊息佇列,並給出具體的程式碼範例。一、分散式事務分散式事務是指跨多個資料庫或服務的事務。在分散式系統中,如何確保資料的一致性成為一大挑戰。下面介紹兩種

如何在Java中使用Linux腳本操作實作訊息佇列 如何在Java中使用Linux腳本操作實作訊息佇列 Oct 05, 2023 am 08:09 AM

如何在Java中使用Linux腳本操作實作訊息佇列,需要具體程式碼範例訊息佇列是一種常見的通訊機制,用於在不同行程之間傳遞資料。在Java中,我們可以使用Linux腳本操作來實作訊息佇列,這樣可以輕鬆地將訊息傳送到佇列或從佇列接收訊息。在本文中,我們將詳細介紹如何使用Java和Linux腳本來實作訊息佇列,並提供具體的程式碼範例。為了開始使用Java和Lin

深入了解Kafka訊息佇列的底層實作機制 深入了解Kafka訊息佇列的底層實作機制 Feb 01, 2024 am 08:15 AM

Kafka訊息佇列的底層實作原理概述Kafka是一個分散式、可擴展的訊息佇列系統,它可以處理大量的數據,並且具有很高的吞吐量和低延遲。 Kafka最初是由LinkedIn開發的,現在是Apache軟體基金會的頂級專案。架構Kafka是一個分散式系統,由多個伺服器組成。每個伺服器稱為一個節點,每個節點都是一個獨立的進程。節點之間透過網路連接,形成一個集群。 K

如何利用Redis和Golang實現簡單的訊息隊列 如何利用Redis和Golang實現簡單的訊息隊列 Aug 01, 2023 am 08:09 AM

如何利用Redis和Golang實現簡單的訊息佇列引言訊息佇列被廣泛應用於各種應用場景,如解耦系統元件、削峰填谷、非同步通訊等。本文將介紹如何使用Redis和Golang實作簡單的訊息佇列,幫助讀者了解訊息佇列的基本原理和實作方式。 Redis簡介Redis是一個使用C語言編寫的開源記憶體資料庫,提供了鍵值對儲存和其他常用資料結構的處理功能。 Redis以其高性能、

See all articles