RocketMQ(1)-架構原理

雨點的名字發表於2019-06-27

RocketMQ(1)-架構原理

RocketMQ是阿里開源的分散式訊息中介軟體,跟其它中介軟體相比,RocketMQ的特點是純JAVA實現叢集和HA實現相對簡單在發生當機和其它故障時訊息丟失率更低

一、RocketMQ專業術語

先講專業術語的含義,後面會畫流程圖來更好的去理解它們。

Producer

訊息生產者,位於使用者的程式內,Producer通過NameServer獲取所有Broker的路由資訊,根據負載均衡策略選擇將訊息發到哪個Broker,然後呼叫Broker介面提交訊息。

Producer Group

生產者組,簡單來說就是多個傳送同一類訊息的生產者稱之為一個生產者組。

Consumer

訊息消費者,位於使用者程式內。Consumer通過NameServer獲取所有broker的路由資訊後,向Broker傳送Pull請求來獲取訊息資料。Consumer可以以兩種模式啟動,廣播(Broadcast)和叢集(Cluster)廣播模式下,一條訊息會傳送給所有Consumer,叢集模式下訊息只會傳送給一個Consumer

Consumer Group

消費者組,和生產者類似,消費同一類訊息的多個 Consumer 例項組成一個消費者組。

Topic

Topic用於將訊息按主題做劃分,Producer將訊息發往指定的Topic,Consumer訂閱該Topic就可以收到這條訊息。Topic跟傳送方和消費方都沒有強關聯關係,傳送方可以同時往多個Topic投放訊息,消費方也可以訂閱多個Topic的訊息。在RocketMQ中,Topic是一個上邏輯概念。訊息儲存不會按Topic分開

Message

代表一條訊息,使用MessageId唯一識別,使用者在傳送時可以設定messageKey,便於之後查詢和跟蹤。一個 Message 必須指定 Topic,相當於寄信的地址。Message 還有一個可選的 Tag 設定,以便消費端可以基於 Tag 進行過濾訊息。也可以新增額外的鍵值對,例如你需要一個業務 key 來查詢 Broker 上的訊息,方便在開發過程中診斷問題。

Tag

標籤可以被認為是對 Topic 進一步細化。一般在相同業務模組中通過引入標籤來標記不同用途的訊息。

Broker

Broker是RocketMQ的核心模組,負責接收並儲存訊息,同時提供Push/Pull介面來將訊息傳送給Consumer。Consumer可選擇從Master或者Slave讀取資料。多個主/從組成Broker叢集,叢集內的Master節點之間不做資料互動。Broker同時提供訊息查詢的功能,可以通過MessageID和MessageKey來查詢訊息。Borker會將自己的Topic配置資訊實時同步到NameServer。

Queue

Topic和Queue是1對多的關係一個Topic下可以包含多個Queue,主要用於負載均衡。傳送訊息時,使用者只指定Topic,Producer會根據Topic的路由資訊選擇具體發到哪個Queue上。Consumer訂閱訊息時,會根據負載均衡策略決定訂閱哪些Queue的訊息。

Offset

RocketMQ在儲存訊息時會為每個Topic下的每個Queue生成一個訊息的索引檔案,每個Queue都對應一個Offset記錄當前Queue中訊息條數

NameServer

NameServer可以看作是RocketMQ的註冊中心,它管理兩部分資料:叢集的Topic-Queue的路由配置;Broker的實時配置資訊。其它模組通過Nameserv提供的介面獲取最新的Topic配置和路由資訊。

  • Producer/Consumer :通過查詢介面獲取Topic對應的Broker的地址資訊
  • Broker : 註冊配置資訊到NameServer, 實時更新Topic資訊到NameServer


二、流程圖

我們由簡單到複雜的來理解,它的一些核心概念
RocketMQ(1)-架構原理

這個圖很好理解,訊息先發到Topic,然後消費者去Topic拿訊息。只是Topic在這裡只是個概念,那它到底是怎麼儲存訊息資料的呢,這裡就要引入Broker概念。

2、Topic的儲存

​ Topic是一個邏輯上的概念,實際上Message是在每個Broker上以Queue的形式記錄。
RocketMQ(1)-架構原理

從上面的圖片可以總結下幾條結論。

1、消費者傳送的Message會在Broker中的Queue佇列中記錄。
2、一個Topic的資料可能會存在多個Broker中。
3、一個Broker存在多個Queue。
4、單個的Queue也可能儲存多個Topic的訊息。

也就是說每個Topic在Broker上會劃分成幾個邏輯佇列,每個邏輯佇列儲存一部分訊息資料,但是儲存的訊息資料實際上不是真正的訊息資料,而是指向commit log的訊息索引。

Queue不是真正儲存Message的地方,真正儲存Message的地方是在CommitLog

如圖(盜圖)
RocketMQ(1)-架構原理

左邊的是CommitLog。這個是真正儲存訊息的地方。RocketMQ所有生產者的訊息都是往這一個地方存的。

右邊是ConsumeQueue。這是一個邏輯佇列。和上文中Topic下的Queue是一一對應的。消費者是直接和ConsumeQueue打交道。ConsumeQueue記錄了消費位點,這個消費位點關聯了commitlog的位置。所以即使ConsumeQueue出問題,只要commitlog還在,訊息就沒丟,可以恢復出來。還可以通過修改消費位點來重放或跳過一些訊息。

3、部署模型

在部署RocketMQ時,會部署兩種角色。NameServer和Broker。如圖(盜圖)
RocketMQ(1)-架構原理

針對這張圖做個說明

1、Product和consumer叢集部署,是你開發的專案進行叢集部署。
2、Broker 叢集部署是為了高可用,因為Broker是真正儲存Message的地方,叢集部署是為了避免一臺掛掉,導致整個專案KO.

那Name SerVer是做什麼用呢,它和Product、Consumer、Broker之前存在怎樣的關係呢?

先簡單概括Name Server的特點

1、Name Server是一個幾乎無狀態節點,可叢集部署,節點之間無任何資訊同步。
2、每個Broker與Name Server叢集中的所有節點建立長連線,定時註冊Topic資訊到所有Name Server。
3、Producer與Name Server叢集中的其中一個節點(隨機選擇)建立長連線,定期從Name Server取Topic路由資訊。
4、Consumer與Name Server叢集中的其中一個節點(隨機選擇)建立長連線,定期從Name Server取Topic路由資訊。

這裡面最核心的是每個Broker與Name Server叢集中的所有節點建立長連線這樣做好處多多。

1、這樣可以使Name Server之間可以沒有任何關聯,因為它們繫結的Broker是一致的。

2、作為Producer或者Consumer可以繫結任何一個Name Server 因為它們都是一樣的。


三、詳解Broker

1、Broker與Name Server關係

1)連線 單個Broker和所有Name Server保持長連線。

2)心跳

心跳間隔:每隔30秒向所有NameServer傳送心跳,心跳包含了自身的Topic配置資訊。

心跳超時:NameServer每隔10秒,掃描所有還存活的Broker連線,若某個連線2分鐘內沒有傳送心跳資料,則斷開連線。

3)斷開 :當Broker掛掉;NameServer會根據心跳超時主動關閉連線,一旦連線斷開,會更新Topic與佇列的對應關係,但不會通知生產者和消費者。

2、 負載均衡

一個Topic分佈在多個Broker上,一個Broker可以配置多個Topic,它們是多對多的關係。
如果某個Topic訊息量很大,應該給它多配置幾個Queue,並且儘量多分佈在不同Broker上,減輕某個Broker的壓力。

3 、可用性

由於訊息分佈在各個Broker上,一旦某個Broker當機,則該Broker上的訊息讀寫都會受到影響。

所以RocketMQ提供了Master/Slave的結構,Salve定時從Master同步資料,如果Master當機,則Slave提供消費服務,但是不能寫入訊息,此過程對應用透明,由RocketMQ內部解決。
有兩個關鍵點:
思考1一旦某個broker master當機,生產者和消費者多久才能發現?

受限於Rocketmq的網路連線機制,預設情況下最多需要30秒,因為消費者每隔30秒從nameserver獲取所有topic的最新佇列情況,這意味著某個broker如果當機,客戶端最多要30秒才能感知。

思考2 master恢復恢復後,訊息能否恢復。
消費者得到Master當機通知後,轉向Slave消費,但是Slave不能保證Master的訊息100%都同步過來了,因此會有少量的訊息丟失。但是訊息最終不會丟的,一旦Master恢復,未同步過去的訊息會被消費掉。


四 Consumer (消費者)

1 、Consumer與Name Server關係

1)連線 : 單個Consumer和一臺NameServer保持長連線,如果該NameServer掛掉,消費者會自動連線下一個NameServer,直到有可用連線為止,並能自動重連。
2)心跳: 與NameServer沒有心跳
3)輪詢時間 : 預設情況下,消費者每隔30秒從NameServer獲取所有Topic的最新佇列情況,這意味著某個Broker如果當機,客戶端最多要30秒才能感知。

2、 Consumer與Broker關係

1)連線 :單個消費者和該消費者關聯的所有broker保持長連線。

3、 負載均衡

叢集消費模式下,一個消費者叢集多臺機器共同消費一個Topic的多個佇列,一個佇列只會被一個消費者消費。如果某個消費者掛掉,分組內其它消費者會接替掛掉的消費者繼續消費。


五、 Producer(生產者)

1、 Producer與Name Server關係

1)連線 單個Producer和一臺NameServer保持長連線,如果該NameServer掛掉,生產者會自動連線下一個NameServer,直到有可用連線為止,並能自動重連。
2)輪詢時間 預設情況下,生產者每隔30秒從NameServer獲取所有Topic的最新佇列情況,這意味著某個Broker如果當機,生產者最多要30秒才能感知,在此期間,
發往該broker的訊息傳送失敗。
3)心跳 與nameserver沒有心跳

2、 與broker關係

連線 單個生產者和該生產者關聯的所有broker保持長連線。


參考

1、十分鐘入門RocketMQ

2、RocketMQ nameserver、broker之間的關係

3、RocketMQ-NameServer




只要自己變優秀了,其他的事情才會跟著好起來(中將8)

相關文章