RocketMQ HA集羣方案

 1、瞭解RocketMQ

1.1、RocketMQ的前世今生

        RocketMQ是阿里開源的一款十分優秀的消息隊列,rocketMQ具有很多其他消息隊列不具有的特性,更重要的是rocketMQ是用java開發的學習成本較低,並且經歷了雙11的數據洪峯的考驗。rocketMQ已經加入了apache,成爲apache的頂級項目。

1.2、相關鏈接

RocketMQ的官網:http://rocketmq.apache.org/

RocketMQ的gitHub:https://github.com/apache/rocketmq

1.2、RocketMQ的架構圖和相關概念

1.2.1、RocketMQ的架構圖

RocketMQ架構分爲四個模塊:NameServer, Broker,Producer,Consumer

 

1.2.2、RocketMQ的相關概念

  • NameServer

          Namesrv 是由阿里雲RocketMQ中間件開發團隊開發的基於服務註冊發現功能的無狀態組件,支持獨立部署。Namesrv在整個RocketMQ架構體系中,屬於重中之重的組件,乃靈魂級組件,統籌全局,可謂之'一家之主'。上可撩得生產者靚妹,下可駕馭消費者御姐,亦可跟broker徐娘親近。

          那麼它又是如何工作的呢?

          1、生產者從namesrv中獲取可用的broker地址,將消息發送至broker。
          2、消費者從namesrv中獲取可用的broker地址,從broker中拉去消息。
          3、broker定時向naemsrv發送心跳信息,維護可用broker地址。

         相對來說,nameserver的穩定性非常高。原因有二: 
         1、 nameserver互相獨立,彼此沒有通信關係,單臺nameserver掛掉,不影響其他nameserver,即使全部掛掉,也不影響業務系統使用,這點類似於dubbo的zookeeper。 
         2 、nameserver不會有頻繁的讀寫,所以性能開銷非常小,穩定性很高。

         NameServer類似於SpringCloud中的eureka

  • Broker

          Broker部署相對複雜,Broker分爲Master與Slave,一個Master可以對應多個Slave,但是一個Slave只能對應一個Master,Master與Slave的對應關係通過指定相同的BrokerName,不同的BrokerId來定義,BrokerId爲0表示            Master,非0表示Slave。Master也可以部署多個。每個Broker與Name Server集羣中的所有節點建立長連接,定時註冊Topic信息到所有Name Server。

          與nameserver關係 :連接 :單個broker和所有nameserver保持長連接 
         心跳 : 心跳間隔每隔30秒(此時間無法更改)向所有nameserver發送心跳,心跳包含了自身的topic配置信息。  心跳超時nameserver每隔10秒鐘(此時間無法更改),掃描所有還存活的broker連接,若某個連接2分鐘內(當前時間與最後更新時間差值超過2分鐘,此時間無法更改)沒有發送心跳數據,則斷開連接。 
         斷開 :時機broker掛掉;心跳超時導致nameserver主動關閉連接 ; 動作一旦連接斷開,nameserver會立即感知,更新topc與隊列的對應關係,但不會通知生產者和消費者

         可用性 :由於消息分佈在各個broker上,一旦某個broker宕機,則該broker上的消息讀寫都會受到影響。所以rocketmq提供了master/slave的結構,salve定時從master同步數據,如果master宕機,則slave提供消費服務,但是不能寫入消息,此過程對應用透明,由rocketmq內部解決。  這裏有兩個關鍵點: 一旦某個broker master宕機,生產者和消費者多久才能發現?受限於rocketmq的網絡連接機制,默認情況下,最多需要30秒,但這個時間可由應用設定參數來縮短時間。這個時間段內,發往該broker的消息都是失敗的,而且該broker的消息無法消費,因爲此時消費者不知道該broker已經掛掉。 消費者得到master宕機通知後,轉向slave消費,但是slave不能保證master的消息100%都同步過來了,因此會有少量的消息丟失。但是消息最終不會丟的,一旦master恢復,未同步過去的消息會被消費掉。

         可靠性 :所有發往broker的消息,有同步刷盤和異步刷盤機制,總的來說,可靠性非常高 。同步刷盤時,消息寫入物理文件纔會返回成功,因此非常可靠 ;異步刷盤時,只有機器宕機,纔會產生消息丟失,broker掛掉可能會發生,但是機器宕機崩潰是很少發生的,除非突然斷電 。

 

  • Producer

      與nameserver關係 :連接 ,單個生產者者和一臺nameserver保持長連接,定時查詢topic配置信息,如果該nameserver掛掉,生產者會自動連接下一個nameserver,直到有可用連接爲止,並能自動重連。 
輪詢時間 :默認情況下,生產者每隔30秒從nameserver獲取所有topic的最新隊列情況,這意味着某個broker如果宕機,生產者最多要30秒才能感知,在此期間,發往該broker的消息發送失敗。該時間由DefaultMQProducer的pollNameServerInteval參數決定,可手動配置。 
心跳 :與nameserver沒有心跳

       與broker關係 :連接 :單個生產者和該生產者關聯的所有broker保持長連接。 
       心跳 :默認情況下,生產者每隔30秒向所有broker發送心跳,該時間由DefaultMQProducer的heartbeatBrokerInterval參數決定,可手動配置。broker每隔10秒鐘(此時間無法更改),掃描所有還存活的連接,若某個連接2分鐘內(當前時間與最後更新時間差值超過2分鐘,此時間無法更改)沒有發送心跳數據,則關閉連接。 
       連接斷開 :移除broker上的生產者信息

  • Consume

      與nameserver關係 :連接 :單個消費者和一臺nameserver保持長連接,定時查詢topic配置信息,如果該nameserver掛掉,消費者會自動連接下一個nameserver,直到有可用連接爲止,並能自動重連。 
      心跳 :與nameserver沒有心跳 
      輪詢時間 :默認情況下,消費者每隔30秒從nameserver獲取所有topic的最新隊列情況,這意味着某個broker如果宕機,客戶端最多要30秒才能感知。該時間由DefaultMQPushConsumer的pollNameServerInteval參數決定,可手動配置。

      與broker關係 :連接 :單個消費者和該消費者關聯的所有broker保持長連接。 

      心跳 :默認情況下,消費者每隔30秒向所有broker發送心跳,該時間由DefaultMQPushConsumer的heartbeatBrokerInterval參數決定,可手動配置。broker每隔10秒鐘(此時間無法更改),掃描所有還存活的連接,若某個連接2分鐘內(當前時間與最後更新時間差值超過2分鐘,此時間無法更改)沒有發送心跳數據,則關閉連接,並向該消費者分組的所有消費者發出通知,分組內消費者重新分配隊列繼續消費 
      斷開 :時機:消費者掛掉;心跳超時導致broker主動關閉連接 ;動作:一旦連接斷開,broker會立即感知到,並向該消費者分組的所有消費者發出通知,分組內消費者重新分配隊列繼續消費

      負載均衡 :集羣消費模式下,一個消費者集羣多臺機器共同消費一個topic的多個隊列,一個隊列只會被一個消費者消費。如果某個消費者掛掉,分組內其它消費者會接替掛掉的消費者繼續消費。

      消費機制 :本地隊列 :消費者不間斷的從broker拉取消息,消息拉取到本地隊列,然後本地消費線程消費本地消息隊列,只是一個異步過程,拉取線程不會等待本地消費線程,這種模式實時性非常高。對消費者對本地隊列有一個保護,因此本地消息隊列不能無限大,否則可能會佔用大量內存,本地隊列大小由DefaultMQPushConsumer的pullThresholdForQueue屬性控制,默認1000,可手動設置。 
     輪詢間隔 :消息拉取線程每隔多久拉取一次?間隔時間由DefaultMQPushConsumer的pullInterval屬性控制,默認爲0,可手動設置。 
     消息消費數量 :監聽器每次接受本地隊列的消息是多少條?這個參數由DefaultMQPushConsumer的consumeMessageBatchMaxSize屬性控制,默認爲1,可手動設置。

2、高可用、集羣概念

2.1、什麼是高可用?

        高可用HA(High Availability)是分佈式系統架構設計中必須考慮的因素之一,它通常是指,通過設計減少系統不能提供服務的時間。

        假設系統一直能夠提供服務,我們說系統的可用性是100%。

        如果系統每運行100個時間單位,會有1個時間單位無法提供服務,我們說系統的可用性是99%。

        很多公司的高可用目標是4個9,也就是99.99%,這就意味着,系統的年停機時間爲8.76個小時。

2.2、如何保障系統的高可用?

        我們都知道,單點是系統高可用的大敵,單點往往是系統高可用最大的風險和敵人,應該儘量在系統設計的過程中避免單點。方法論上,高可用保證的原則是“集羣化”,或者叫“冗餘”:只有一個單點,掛了服務會受影響;如果有冗餘備份,掛了還有其他backup能夠頂上。

保證系統高可用,架構設計的核心準則是:冗餘。

有了冗餘之後,還不夠,每次出現故障需要人工介入恢復勢必會增加系統的不可服務實踐。所以,又往往是通過“自動故障轉移”來實現系統的高可用。

2.3、集羣的概念

       將同一個業務部署在多臺服務器上,如果主機宕機了,其它服務器可以自動接替主機服務器工作,以實現持續性爲客戶提供服務,並且處理科研實驗以及核處理等大型計算業務,單臺大型計算機依然無法勝任,集羣可以將一個計算業務交給集羣中的多臺計算機進行處理。

2.4、集羣的特點

  • 可擴展性:集羣的性能不限制於單一的服務實體,新的服務實體可以動態的添加到集羣,從而增強了集羣的性能。
  • 高可用性:集羣當其中一個節點發生故障時,這臺節點上所運行的應用程序將在另一臺節點被自動接管,消除單點故障對於增強數據可用性、可達性和可靠性是非常重要的。

3、RocketMQ的HA方案

3.1、namesrv 集羣部署

        RocketMQ如何做集羣部署來提供系統的吞吐量,以及高可用性?從整體的架構上便可一眼看出,服務註冊與發現組件namesrv可以獨立部署,且namesrv與namesrv之間並無直接或間接的關聯,雙方不存在心跳檢測,所以namesrv的之間不存在主備切換過程,如果其中一臺namesrv宕機後,生產者消費者會直接從另一臺namesrv中請求數據。但也正因爲namesrv之間不存在心跳檢測,主備切換,所以無法支持動態擴容,當機器宕機需要重新部署基於新的ip地址的namesrv需要更新生產者/消費者直連的namesrv地址。

3.2、broker 集羣部署

   broker支持主從架構

broker支持主從架構模式,但是並非是非常完善的主從架構,據說會在後續版本中優化。

主從架構模式爲何會說不是完善的主從架構呢?說到主從 架構模式,大家最熟悉,最耳熟能詳的必然是MySQL的主從讀寫分離模式。主庫支持writer,比如insert/update/delete等對數據產生修改的操作,而從庫則只支持read操作,這種架構設計是基於目前互聯網讀多寫少的業務模式。

那麼RocketMQ又是提供了何種主從讀寫分離的模式呢?

1、目前它支持master寫操作,只有當master讀壓力高於某個點(master消息拉取出現堆積時),纔會將讀壓力轉給salver。
2、無法做到主從切換,master宕機,salver只能提供消息消費,salver不會被選舉爲master來繼續工作。如果master宕機,消息隊列整個環境近乎癱瘓。

 主從複製

決定rocketmq是否爲master還是slaver,是從配置文件中讀取設定的,如下:

public enum BrokerRole {
    ASYNC_MASTER,
    SYNC_MASTER,
    SLAVE;
}

ASYNC_MASTER:異步master,也就是新的消息存儲時不需要等slave同步好; 
SYNC_MASTER:同步master,新消息存現時需要等slave同步好(也就是返回的 Ack Offset >= 當前消息的CommitLog Offset;)
Slave:指該brokder爲slaver;

當master啓動是,是不會主動向slaver同步數據的。當slaver啓動時,會上報當前的commitlog offset偏移值。一般會有兩種情況,一種是slaver是全新的機器,commitlog是空的,傳遞maxPhyOffset=0。一種是master在使用過程中宕機了,經運維人員修復後重啓成功,繼續工作,master會根據slaver上報的maxPhyOffset的值繼續同步。

多master多salver場景

如果用戶體量稍微大一些,單master單slaver扛不住,可以採用多master/多slaver部署架構。

broker同步/異步刷盤

前文中我們提到,RocketMQ是基於高性能低延遲的文件儲存,爲了讓用戶在使用過程中可以按照自己對消息的丟失容忍程度與性能之間做一個選擇,RocketMQ提供了兩種方式刷盤方式,即同步刷盤/異步刷盤。顧名思義,同步刷盤指消息投放到broker之後,會在寫入文件之後才返回成功,而異步刷盤則指消息投放broker成功後即可返回,同時啓動另外的線程來存儲消息。

同步刷盤的有點非常明顯,可以保證消息可靠性,但是性能上無疑要略遜一籌。
異步刷盤反其道而行之,性能上肯定有了顯著提高,但是消息可靠性卻無所保證,因爲在文件寫入過程失敗,無法通知生產者重試。

部署方式 優點 缺點 備註
單個Master模式 一旦Broker重啓或者宕機時,會導致整個服務不可用,不建議線上環境使用; 單臺機器宕機期間,這臺機器上未被消費的消息在機器恢復之前不可訂閱,消息實時性會收到影響。  
多個Master模式 配置簡單,單個Master宕機或重啓維護對應用無影響,在磁盤配置爲RAID10時,即使機器宕機不可恢復情況下,由於RAID10磁盤非常可靠,消息也不會丟(異步刷盤丟失少量消息,同步刷盤一條不丟),性能最高。 Master宕機,磁盤損壞情況,會丟失少量信息。 當使用多master無slave的集羣搭建方式時,master的brokerRole配置必須爲ASYNC_MASTER。如果配置爲SYNC_MASTER,則producer發送消息時,返回值的SendStatus會一直是SLAVE_NOT_AVAILABLE。
多Master多Slave模式——異步複製 即使磁盤損壞,消息丟失的非常少,但消息實時性不會受影響,因爲Master宕機後,消費者仍然可以從Slave消費,此過程對應用透明,不需要人工干預,性能同多Master模式幾乎一樣。 性能比異步複製模式稍低,大約低10%左右,發送單個消息的RT會稍高,目前主宕機後,備機不能自動切換爲主機,後續會支持自動切換功能。  
多Master多Slave模式——同步雙寫 數據與服務都無單點,Master宕機情況下,消息無延遲,服務可用性與數據可用性都非常高;    

所以broker的高可用就是:master slave 配合,master 支持讀、寫,slave 只讀,producer 只能和 master 連接寫入消息,consumer 可以連接 master 和 slave。

3.3、Producer的高可用

創建 topic 時,把 message queue 創建在多個 broker 組上(brokerName 一樣,brokerId 不同),當一個 broker 組的 master 不可用後,其他組的 master 仍然可以用,producer 可以繼續發消息。

3.4、Consumer的高可用

當 master 不可用或者繁忙時,consumer 會被自動切換到 slave 讀。所以,即使 master 出現故障,consumer 仍然可以從 slave 讀消息,不受影響。
 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章