RocketMQ4.2 最佳實踐之集群搭建
- 2019 年 11 月 6 日
- 筆記
學習了RocketMQ的基本概念後,我們來看看RocketMQ最簡單的使用場景。RocketMQ的伺服器最簡單的結構,必須包含一個NameServer和一個Broker。Producer把某個主題的消息發送給Broker,Consumer會去Broker中監聽指定主題的消息,一旦發現,就會拉取並消費。在這個過程中,Producer和Consumer是通過NameServer才知道Broker部署在哪裡,如果是 Broker Cluster 的情況,還要知道Master節點是哪些。換句話說,NameServer中保存著 Broker 的路由資訊。
以上這些理解是對 RocketMQ 最淺顯直觀的理解。然後我們來試想一下,如果 NameServer 和 Broker 都是單節點的,那麼一旦出現問題,首先是服務不可用了,其次,Producer和Consumer必然不知道Broker在哪裡,消息就會發不出去也監聽不到。Broker中尚未被消費的消息必然在故障期間不可訂閱,影響消息實時性。為了避免這種情況的發生,我們需要搭建NameServer集群和 Broker 集群。
本文主要講解【MQ集群】和【Broker Set】的搭建方法,其中也涉及到了名詞解釋和各組件作用的簡單介紹。【MQ集群】和【Broker Set】的搭建,主要是為了最大程度上保證消息不丟失,從而做到 RocketMQ 的高可用。
1. 集群物理部署結構
以多Master多Slave模式為例,看一下RocketMQ集群物理部署結構,然後我們解釋一下基本概念:

=== NameServer Cluster ===
NameServer是一個幾乎無狀態節點,可集群部署,節點之間無任何資訊同步,只要保證一個實例存活就可以正常提供Broker的路由資訊。如上圖所示。
=== Broker Cluster ===
Broker分為Master和Slave,一個Master可以對應多個Slave,但是一個Slave只能對應一個Master。Master與Slave的對應關係通過指定相同的BrokerName,不同的BrokerId來定義,BrokerId為0表示Master,非0表示Slave。因為這些 Master 和 Slave 具有相同的 BrokerName,因此它們組成了一個 Broker Set。
Master Broker 也可以部署多個。每個Broker或者 Broker Set 與NameServer集群中的所有節點建立長連接,定時註冊 Topic 資訊到所有 NameServer。
=== Producer Cluster ===
Producer與NameServer集群中的其中一個節點(隨機選擇)建立長連接,定期從NameServer取Topic路由資訊,並和提供Topic服務的Master建立長連接,且定時向Master發送心跳。Producer完全無狀態,可集群部署。
=== Consumer Cluster ===
Consumer與NameServer集群中的其中一個節點(隨機選擇)建立長連接,定期從NameServer取Topic路由資訊,並和提供Topic服務的Master、Slave建立長連接,且定時向Master、Slave發送心跳。Consumer既可以從Master訂閱消息,也可以從Slave訂閱消息,訂閱規則由Broker配置決定。
2. 消息落盤和Broker數據同步
搭建 RocketMQ 集群的目的,是為了在最大程度上保證消息不丟失。下面我們來看看集群中有哪些特性,可以保障消息不丟失。
2.1 消息落盤
RocketMQ可以將記憶體中的數據存儲在磁碟中,這種操作叫做磁碟刷新(Disk Flush)。
RocketMQ提供了以下兩種模式:
- SYNC_FLUSH(同步刷盤):生產者發送的每一條消息,都在保存到磁碟成功後才回調告訴生產者成功。這種方式不會存在消息丟失的問題,但是有很大的磁碟IO開銷,性能有一定影響
- ASYNC_FLUSH(非同步刷盤):生產者發送的每一條消息並不是立即保存到磁碟,而是暫時快取起來,然後就回調告訴生產者成功。隨後再非同步的將快取數據保存到磁碟
如果我們選擇非同步刷盤,可選的有兩種刷盤機制:
- 定期將快取中更新的數據進行落盤
- 當快取中更新的數據條數達到某一設定值後進行落盤。這種方式會存在消息丟失(在還未來得及同步到磁碟的時候宕機),但是性能很好。默認是這種模式。
2.2 Broker數據同步機制
Broker Replication(Broker 間數據同步/複製):
Broker Replication 指的就是在一個Broker Set 中,Slave Broker 獲取/複製 Master Broker 數據的過程。這裡再提一下 Broker Set 的概念。
Broker Set 中的Broker,有兩種角色:
- 一種是master,即可以寫也可以讀,其brokerId=0,只能有一個
- 一種是slave,只允許讀,其brokerId為非0
一個master與多個slave通過指定相同的BrokerName被歸為一個 broker set(broker集)。通常生產環境中,我們至少需要2個broker set。
生產者發送的消息,總是先發到 Master Broker。對於消息發送成功的回調,Broker Set 有兩種數據同步機制:
- Sync Broker(同步雙寫):生產者發送的每一條消息都至少同步複製到一個slave後,才返回告訴生產者成功,即“同步雙寫”
- Async Broker(非同步複製):生產者發送的每一條消息只要寫入master,就返回告訴生產者成功。然後再“非同步複製”到slave
幾種Broker集群搭建的最佳實踐:
2M + NoSlave:兩主(只有兩個master,沒有slave)
2M + 2S + Async:兩主兩從非同步複製(兩個master,兩個slave,master數據通過非同步複製到slave)
2M + 2S + Sync:兩主兩從同步雙寫(兩個master,兩個slave,數據同步雙寫到master和slave)
說明:
- 上述“2”只是說作為一個集群的最低配置數量,可以根據實際情況擴展
- 所有的刷盤操作全部默認為:ASYNC_FLUSH(非同步刷盤)
3. 三種Broker集群方式優缺點
多Master模式(2M + NoSlave)
一個集群無Slave,全是Master,例如2個Master或者3個Master。
Master之間有負載均衡,Producer發出的消息會平均地落在Master機器上。但是對於一條消息,只會落在一台Master上。
優點:配置簡單,單個Master宕機或重啟維護時,對應用無影響。當磁碟配置為RAID10時,即使機器宕機不可恢復情況下,由於RAID10磁碟非常可靠,消息也不會丟(非同步刷盤情況丟失少量消息,同步刷盤情況一條不丟)。性能最高。
缺點:單台機器宕機期間,這台機器上未被消費的消息在機器恢復之前不可訂閱,消息實時性會受到影響。
多Master多Slave模式,非同步複製(2M + 2S + Async)
每個Master配置一個Slave,有多對Master-Slave,HA採用非同步複製方式,主備有短暫消息延遲,毫秒級。
優點:即使磁碟損壞,消息丟失的非常少,且消息實時性不會受影響,因為Master宕機後,消費者仍然可以從Slave消費,此過程對應用透明。另外,不需要人工干預。性能同多Master模式幾乎一樣。
缺點:Master宕機,磁碟損壞情況,會丟失少量消息。
多Master多Slave模式,同步雙寫(2M + 2S + Sync)
每個Master配置一個Slave,有多對Master-Slave,HA採用同步雙寫方式,主備都寫成功,嚮應用返回成功。
優點:數據與服務都無單點,Master宕機情況下,消息無延遲,服務可用性與數據可用性都非常高。
缺點:性能比非同步複製模式略低,大約低10%左右,發送單個消息的響應時間會略久。
4. 雙主集群搭建
這裡就以雙主集群為例,進行搭建。
本小節是實際操作的Shell腳本和配置方法,這篇筆記省略。可以閱讀參考資料來查看。
5. 雙主雙從集群搭建
前文已經搭建過雙主結構的MQ集群,這種集群能滿足我們日常的需要,但是有時候我們會遇到這樣的場景,我們會要求消息實時返回,那麼雙主結構的能否滿足我們的需求呢?
答案是,極端情況下消息做不到實時。試想有一台Master突然宕機或者網路不好而斷開,而恰巧,宕機的Master節點中還有消息沒有被消費,那麼這個消息將不會被消費者獲得,只有等宕機的Master節點重新啟動,存在於該節點的消息才會被消費。在這段時間內,那些消息是不可訂閱的,影響了實時性。
要想解決上面的問題,我們可以搭建雙主雙從的集群。讓我們回顧一下,雙主雙從的數據同步機制,一般有兩種:
- Sync Broker(同步雙寫):當生產端生產消息後,主節點和從節點都收到消息,並把消息都同時寫入到本地後,才會回復消息
- Async Broker(非同步複製):當主節點將數據保存到本地後,直接返回成功的消息,不關係從節點是否寫入成功
我們可以看出,非同步複製效率比較高,而同步雙寫更具有高可用性,數據也變得更加可靠。
下面我們搭建雙主雙從集群,並採用非同步複製的方式。具體的搭建方式,請自行網上查找資料。再來看一下搭建完成後的結構圖:

搭建完成後,對集群進行測試,還是以上圖為例,可以看到下面的情況:
- 消息發送時已經進行了負載均衡,消息比較平均地落在了兩個 Broker Set 上
- 在Broker運行時關掉 Broker Master1,Broker Master1 上還沒有被消費的數據,會走 Broker Slave1被消費。消費完了再把 Broker Master1 啟動,Master1 上沒有被消費的數據不會被消費
- 在Broker運行時關掉 Broker Master1,之後的消息會被發到 Broker Master2 上
- 當Master1被加回來,Master1會重新成為主節點,並且與 Master2 還是有負載均衡效果
- Slave1 在 Master1 宕機期間,不會升級成為主節點
6. 參考資料
https://www.jianshu.com/p/616474a5c4a7
創作時間:2019-06-14 16:17