騰訊雲分佈式高可靠消息隊列CMQ架構


作者:張浩              

出處:騰雲閣文章

----------------------



在分佈式大行其道的今天,我們在系統內部、平臺之間廣泛運用消息中間件進行數據交換及解耦。CMQ是騰訊雲內部自研基於的高可靠、強一致、可擴展分佈式消息隊列,在騰訊內部包括微信手機QQ業務紅包、騰訊話費充值、廣告訂單等都有廣泛使用。目前已上線騰訊雲對外開放,本文對騰訊雲CMQ 核心技術原理進行分享介紹。

CMQ消息隊列主要適用於金融、交易、訂單等對可靠性、可用性有較高要求的業務場景。

以騰訊充值系統爲例,該充值系統通過CMQ 對交易模塊、發貨部分、結算系統進行異步解耦、削峯填谷,一方面大大降低了模塊間耦合度,另一方面減輕了大量突發請求對後端系統的衝擊。在月初充值該系統一天經過CMQ轉發的消息超過十億條,每秒峯值超過10w,最高時有數億條消息通過CMQ的堆積能力緩衝了對後端消費模塊的壓力。架構如圖1:

圖1-某充值系統結構
圖中騰訊雲消息隊列CMQ整體結構如圖2所示,本文重點介紹後端broker set實現原理。通常情況下一個set由3個節點組成,通過多副本保證消息的可靠性、多節點提高系統可用性。當然,可以根據業務的實際需求通過增加set內節點個數來進一步提高可靠性和可用性,

圖2-CMQ整體架構圖

CMQ set 模塊內部結構如圖3所示。

圖3-brokerset 內部結構圖

下面分別中數據高可靠、強一致,系統可用性,可擴展、消息全路徑追蹤方面分別介紹。
在可靠性保證方面主要包括以下三方面:生產可靠、存儲(堆積)可靠、消費可靠:

生產可靠

如圖3所示,客戶端生產的消息在set 中超過半數的broker 刷盤成功後會返回確認消息告知生產消息成功。如果在一定時間之內客戶端沒有收到確認信息需要重試來確保消息發送成功。

可靠生產帶來的一個問題就是消息的重複,在網絡異常等情況下很可能CMQ broker已經存儲消息成功只是確認包在網絡上丟失了,這樣客戶端重試生產後,在broker上存在兩條重複的消息。考慮到消息去重開銷較大,目前消息的冪等性需要業務邏輯來保證。

存儲可靠

CMQ SET中一個節點爲leader 其他節點爲follower,leader 負責所有消息的生產消費。當生產消息到達leader 節點後,通過raft 一致性模塊將請求順序寫raft log 並同步刷盤,同時將構造好的raft log 按順序通過網絡發送到其他follower節點,follower節點同步刷盤並返回成功。當leader 收到過半數的節點同步成功信息後將此條請求提交到mq 處理狀態機,由mq 狀態機將請求應用到相應queue。大致邏輯圖4所示。

圖4-數據存儲原理示意圖

由此可見,對於返回客戶端成功的消息至少是分別在兩個節點磁盤上存儲成功的,這就將磁盤故障引起的數據丟失大大降低。另外數據在磁盤上存儲時會將檢驗結果一同記下來,消費者在消費數據之前CMQ broker 會進行比較,確保消息是完整有效的。

消費可靠

消費者拉取消息時會指定當前消息的隱藏時間,在隱藏時間內消費者比較顯式的對消息進行確認刪除,如果超過隱藏時間沒有主動刪除,此條消息將重新對外可見,可以繼續消費。

顯式確認刪除消息是爲了防止消息在投遞、處理過程中異常而導致的消息丟失。

對於消息的確認信息 CMQ broker的處理邏輯和生產消息過程類似,也是一個寫入的過程,不同的是此時寫入的數據的內容是msgid 和消息狀態。

強一致實現

假如一個set中有3個節點(A, B, C),A爲leader,B C 是follower。如上圖所示,對於返回客戶端成功的請求數據在CMQ 中至少在兩個節點上存在,假設爲A B,此時如果leader A故障,B C 兩個follower 會自動選舉出一個新leader,CMQ 使用的raft 算法可以保證這個leader 一定是擁有最全量log 信息中的一個,在此必定是B。此時B繼續對外服務,B 和A 擁有相同的已經返回確認給用戶的全量數據視圖,數據是強一致的。

對於A 和 B C 所在的網絡發生分區的情況(如圖5),由於leader A得不到set 中過半節點的回覆所以不能處理請求,B C在選舉超時後會選舉出一個新的leader ,CMQ的接入層會自動進行切換。Raft 算法保證新leader 同樣具有完成的數據視圖。

可用性保證


如上文所述,master 負責所有消息的生產消費,當master 故障時SET中其他follower節點會自動選舉出一個新leader,客戶端請求會自動重定向到leader節點,RTO和配置的選舉超時時間有關,目前是在5s左右。大致過程如上圖6所示。

CMQ單個set 在CAP理論中優先保證了CP,當SET中過半數節點都正常工作時,才能進行消息的生產消費。對於SET多個節點同時故障的不可用情況,CMQ強大的監控調度能力能夠快速對queue進行調度遷移恢復服務,將不可用時間降到最低。

橫向擴展,無限堆積


上文中SET的概念對用戶來說是透明無感知的,CMQ controller server 根據set的負載情況實時對queue進行調度搬遷。如果某個queue的請求量超過當前set的服務閾值,controller server 可以將queue 路由分佈到多個set 上來提高併發量,對於需要海量堆積的服務來說可以通過路由調度來提升堆積上限,理論上可以達到無限堆積。

目前CMQ只能保證特定情況下消息的嚴格有序,例如需要保證單個生產進程、單個消費進程,或者queue的消費窗口設定爲1等條件。

全路徑消息trace

CMQ系統中,一條消息的完整路徑包含生產者、broker、消費者三個角色,每個角色處理消息的過程中都會在trace 路徑中增加相關的信息,將這些信息匯聚即可獲取任意一條消息的狀態和當前經過的完整路徑,從而爲生產環境中的問題排查提供強有力的數據支持。大大降低了業務定位問題的難度。

小結

CMQ是基於raft 算法來保證數據高可靠、強一致的分佈式消息隊列,主要服務於訂單、交易類業務場景。消息的冪等性需業務側來保證,在特定情況下可以保證消息嚴格有序。
對於更側重高性能、高吞吐量業務需求,騰訊雲由另外一個消息引擎來提供服務,在協議上同時兼容kafka,很好的滿足了大數據場景,具體原理請留意後續文章介紹。



--------------------------------------------------------


獲取更多雲計算技術乾貨,可請前往  騰訊雲技術社區


我也會持續同步更新~


微信公衆號:騰訊雲技術社區( QcloudCommunity)

wKiom1jBYALjrsTKAAAvZ3cJzxs385.jpg-wh_50


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