1. 程式人生 > 程式設計 >RocketMQ深度解析(一):RocketMQ總體設計

RocketMQ深度解析(一):RocketMQ總體設計

設計理念

RocketMQ設計基於主題的釋出和訂閱模式,其核心功能包括訊息傳送、訊息儲存、訊息消費,整體設計追求簡單與效能第一,主要體現在三個方面:

  • 因為Topic路由資訊能容忍分鐘級的不一致。所有RocketMQ的NameServer叢集之間互不通訊,降低了NameServer的複雜程度以及對網路的要求,同時效能比zookeeper有了極大的提升。
  • 高效的IO儲存機制,訊息儲存檔案設計成檔案組的概念,組內單個檔案大小固定,方便引入記憶體對映機制,所有topic的訊息儲存基於順序寫,極大提升了訊息的寫效能,同時為了兼顧訊息消費與訊息查詢,引入了訊息消費佇列檔案與索引檔案。
  • 冪等性問題:RocketMQ不處理,留給使用者處理。

架構設計

技術架構

RocketMQ架構上主要分為四部分,如上圖所示:

  • Producer:訊息釋出的角色,支援分散式叢集方式部署。Producer通過MQ的負載均衡模組選擇相應的Broker叢集佇列進行訊息投遞,投遞的過程支援快速失敗並且低延遲。

  • Consumer:訊息消費的角色,支援分散式叢集方式部署。支援以push推,pull拉兩種模式對訊息進行消費。同時也支援叢集方式和廣播方式的消費,它提供實時訊息訂閱機制,可以滿足大多數使用者的需求。

  • NameServer:NameServer是一個非常簡單的Topic路由註冊中心,其角色類似Dubbo中的zookeeper,支援Broker的動態註冊與發現。主要包括兩個功能:Broker管理,NameServer接受Broker叢集的註冊資訊並且儲存下來作為路由資訊的基本資料。然後提供心跳檢測機制,檢查Broker是否還存活;路由資訊管理,每個NameServer將儲存關於Broker叢集的整個路由資訊和用於客戶端查詢的佇列資訊。然後Producer和Conumser通過NameServer就可以知道整個Broker叢集的路由資訊,從而進行訊息的投遞和消費。NameServer通常也是叢集的方式部署,各例項間相互不進行資訊通訊。Broker是向每一臺NameServer註冊自己的路由資訊,所以每一個NameServer例項上面都儲存一份完整的路由資訊。當某個NameServer因某種原因下線了,Broker仍然可以向其它NameServer同步其路由資訊,Producer,Consumer仍然可以動態感知Broker的路由的資訊。

  • BrokerServer:Broker主要負責訊息的儲存、投遞和查詢以及服務高可用保證。

部署架構

  • ameServer是一個幾乎無狀態節點,可叢集部署,節點之間無任何資訊同步。
  • Broker部署相對複雜,Broker分為Master與Slave,一個Master可以對應多個Slave,但是一個Slave只能對應一個Master,Master與Slave 的對應關係通過指定相同的BrokerName,不同的BrokerId 來定義,BrokerId為0表示Master,非0表示Slave。Master也可以部署多個。每個Broker與NameServer叢集中的所有節點建立長連線,定時註冊Topic資訊到所有NameServer。 注意:當前RocketMQ版本在部署架構上支援一Master多Slave,但只有BrokerId=1的從伺服器才會參與訊息的讀負載。
  • Producer與NameServer叢集中的其中一個節點(隨機選擇)建立長連線,定期從NameServer獲取Topic路由資訊,並向提供Topic 服務的Master建立長連線,且定時向Master傳送心跳。Producer完全無狀態,可叢集部署。
  • Consumer與NameServer叢集中的其中一個節點(隨機選擇)建立長連線,定期從NameServer獲取Topic路由資訊,並向提供Topic服務的Master、Slave建立長連線,且定時向Master、Slave傳送心跳。Consumer既可以從Master訂閱訊息,也可以從Slave訂閱訊息,消費者在向Master拉取訊息時,Master伺服器會根據拉取偏移量與最大偏移量的距離(判斷是否讀老訊息,產生讀I/O),以及從伺服器是否可讀等因素建議下一次是從Master還是Slave拉取。

工作流程

結合部署架構圖,描述叢集工作流程:

  • 啟動NameServer,NameServer起來後監聽埠,等待Broker、Producer、Consumer連上來,相當於一個路由控制中心。
  • Broker啟動,跟所有的NameServer保持長連線,定時傳送心跳包。心跳包中包含當前Broker資訊(IP+埠等)以及儲存所有Topic資訊。註冊成功後,NameServer叢集中就有Topic跟Broker的對映關係。
  • 收發訊息前,先建立Topic,建立Topic時需要指定該Topic要儲存在哪些Broker上,也可以在傳送訊息時自動建立Topic。
  • Producer傳送訊息,啟動時先跟NameServer叢集中的其中一臺建立長連線,並從NameServer中獲取當前傳送的Topic存在哪些Broker上,輪詢從佇列列表中選擇一個佇列,然後與佇列所在的Broker建立長連線從而向Broker發訊息。
  • Consumer跟Producer類似,跟其中一臺NameServer建立長連線,獲取當前訂閱Topic存在哪些Broker上,然後直接跟Broker建立連線通道,開始消費訊息。

參考文獻

  • RocketMQ官方Doc

  • RocketMQ技術內幕