RocketMQ——角色與術語詳解


原文地址:http://jaskey.github.io/blog/2016/12/15/rocketmq-concept/

RocketMQ——角色與術語詳解

2016-12-15 THU 15:48

RocketMQ中有很多概念,其中包括一些術語和角色。

理清楚基本的概念能有效的幫助理解RocketMQ的原理以及排查問題。

角色:

Producer

生產者。發送消息的客戶端角色。發送消息的時候需要指定Topic。

Consumer

消費者。消費消息的客戶端角色。通常是后台處理異步消費的系統。 RocketMQ中Consumer有兩種實現:PushConsumer和PullConsumer。

PushConsumer

推送模式(雖然RocketMQ使用的是長輪詢)的消費者。消息的能及時被消費。使用非常簡單,內部已處理如線程池消費、流控、負載均衡、異常處理等等的各種場景。

PullConsumer

拉取模式的消費者。應用主動控制拉取的時機,怎么拉取,怎么消費等。主動權更高。但要自己處理各種場景。

概念術語

Producer Group

標識發送同一類消息的Producer,通常發送邏輯一致。發送普通消息的時候,僅標識使用,並無特別用處。若事務消息,如果某條發送某條消息的producer-A宕機,使得事務消息一直處於PREPARED狀態並超時,則broker會回查同一個group的其 他producer,確認這條消息應該commit還是rollback。但開源版本並不支持事務消息。

Consumer Group

標識一類Consumer的集合名稱,這類Consumer通常消費一類消息,且消費邏輯一致。同一個Consumer Group下的各個實例將共同消費topic的消息,起到負載均衡的作用。

消費進度以Consumer Group為粒度管理,不同Consumer Group之間消費進度彼此不受影響,即消息A被Consumer Group1消費過,也會再給Consumer Group2消費。

注: RocketMQ要求同一個Consumer Group的消費者必須要擁有相同的注冊信息,即必須要聽一樣的topic(並且tag也一樣)。

Topic

標識一類消息的邏輯名字,消息的邏輯管理單位。無論消息生產還是消費,都需要指定Topic。

Tag

RocketMQ支持給在發送的時候給topic打tag,同一個topic的消息雖然邏輯管理是一樣的。但是消費topic1的時候,如果你訂閱的時候指定的是tagA,那么tagB的消息將不會投遞。

Message Queue

簡稱Queue或Q。消息物理管理單位。一個Topic將有若干個Q。若Topic同時創建在不通的Broker,則不同的broker上都有若干Q,消息將物理地存儲落在不同Broker結點上,具有水平擴展的能力。

無論生產者還是消費者,實際的生產和消費都是針對Q級別。例如Producer發送消息的時候,會預先選擇(默認輪詢)好該Topic下面的某一條Q地發送;Consumer消費的時候也會負載均衡地分配若干個Q,只拉取對應Q的消息。

每一條message queue均對應一個文件,這個文件存儲了實際消息的索引信息。並且即使文件被刪除,也能通過實際純粹的消息文件(commit log)恢復回來。

Offset

RocketMQ中,有很多offset的概念。但通常我們只關心暴露到客戶端的offset。一般我們不特指的話,就是指邏輯Message Queue下面的offset。

注: 邏輯offset的概念在RocketMQ中字面意思實際上和真正的意思有一定差別,這點在設計上顯得有點混亂。祥見下面的解釋。

可以認為一條邏輯的message queue是無限長的數組。一條消息進來下標就會漲1,而這個數組的下標就是offset。

max offset

字面上可以理解為這是標識message queue中的max offset表示消息的最大offset。但是從源碼上看,這個offset實際上是最新消息的offset+1,即:下一條消息的offset。

min offset:

標識現存在的最小offset。而由於消息存儲一段時間后,消費會被物理地從磁盤刪除,message queue的min offset也就對應增長。這意味着比min offset要小的那些消息已經不在broker上了,無法被消費。

consumer offset

字面上,可以理解為標記Consumer Group在一條邏輯Message Queue上,消息消費到哪里即消費進度。但從源碼上看,這個數值是消費過的最新消費的消息offset+1,即實際上表示的是下次拉取的offset位置

消費者拉取消息的時候需要指定offset,broker不主動推送消息, offset的消息返回給客戶端。

consumer剛啟動的時候會獲取持久化的consumer offset,用以決定從哪里開始消費,consumer以此發起第一次請求。

每次消息消費成功后,這個offset在會先更新到內存,而后定時持久化。在集群消費模式下,會同步持久化到broker,而在廣播模式下,則會持久化到本地文件。

集群消費

消費者的一種消費模式。一個Consumer Group中的各個Consumer實例分攤去消費消息,即一條消息只會投遞到一個Consumer Group下面的一個實例。

實際上,每個Consumer是平均分攤Message Queue的去做拉取消費。例如某個Topic有3條Q,其中一個Consumer Group 有 3 個實例(可能是 3 個進程,或者 3 台機器),那么每個實例只消費其中的1條Q。

而由Producer發送消息的時候是輪詢所有的Q,所以消息會平均散落在不同的Q上,可以認為Q上的消息是平均的。那么實例也就平均地消費消息了。

這種模式下,消費進度的存儲會持久化到Broker。

廣播消費

消費者的一種消費模式。消息將對一個Consumer Group下的各個Consumer實例都投遞一遍。即即使這些 Consumer 屬於同一個Consumer Group,消息也會被Consumer Group 中的每個Consumer都消費一次。

實際上,是一個消費組下的每個消費者實例都獲取到了topic下面的每個Message Queue去拉取消費。所以消息會投遞到每個消費者實例。

這種模式下,消費進度會存儲持久化到實例本地。

順序消息

消費消息的順序要同發送消息的順序一致。由於Consumer消費消息的時候是針對Message Queue順序拉取並開始消費,且一條Message Queue只會給一個消費者(集群模式下),所以能夠保證同一個消費者實例對於Q上消息的消費是順序地開始消費(不一定順序消費完成,因為消費可能並行)。

在RocketMQ中,順序消費主要指的是都是Queue級別的局部順序。這一類消息為滿足順序性,必須Producer單線程順序發送,且發送到同一個隊列,這樣Consumer就可以按照Producer發送的順序去消費消息。

生產者發送的時候可以用MessageQueueSelector為某一批消息(通常是有相同的唯一標示id)選擇同一個Queue,則這一批消息的消費將是順序消息(並由同一個consumer完成消息)。或者Message Queue的數量只有1,但這樣消費的實例只能有一個,多出來的實例都會空跑。

普通順序消息

順序消息的一種,正常情況下可以保證完全的順序消息,但是一旦發生異常,Broker宕機或重啟,由於隊列總數發生發化,消費者會觸發負載均衡,而默認地負載均衡算法采取哈希取模平均,這樣負載均衡分配到定位的隊列會發化,使得隊列可能分配到別的實例上,則會短暫地出現消息順序不一致。

如果業務能容忍在集群異常情況(如某個 Broker 宕機或者重啟)下,消息短暫的亂序,使用普通順序方式比較合適。

嚴格順序消息

順序消息的一種,無論正常異常情況都能保證順序,但是犧牲了分布式 Failover 特性,即 Broker集群中只要有一台機器不可用,則整個集群都不可用,服務可用性大大降低。

如果服務器部署為同步雙寫模式,此缺陷可通過備機自動切換為主避免,不過仍然會存在幾分鍾的服務不可用。(依賴同步雙寫,主備自動切換,自動切換功能目前並未實現)

目前已知的應用只有數據庫 binlog 同步強依賴嚴格順序消息,其他應用絕大部分都可以容忍短暫亂序,推薦使用普通的順序消息


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM