国产线精品视频在线观看-国产系列在线亚洲视频-国产系列视频二区-国产午夜在线视频-亚欧日韩毛片在线看免费网站-亚欧免费观看在线观看更新

技術(shù)支持 Support
搜索 Search
你的位置:首頁 > 技術(shù)支持

RocketMQ 客戶端負(fù)載均衡機(jī)制詳解及最佳實踐

2023/1/7 22:14:35      點擊:

前言

Cloud Native

本文介紹 RocketMQ 負(fù)載均衡機(jī)制,主要涉及負(fù)載均衡發(fā)生的時機(jī)、客戶端負(fù)載均衡對消費的影響(消息堆積/消費毛刺等)并且給出一些最佳實踐的推薦。

負(fù)載均衡意義

Cloud Native

上圖是 RocketMQ 的消息儲存模型:消息是按照隊列的方式分區(qū)有序儲存的。RocketMQ 的隊列模型使得生產(chǎn)者、消費者和讀寫隊列都是多對多的映射關(guān)系,彼此之間都可以無限水平擴(kuò)展。對比傳統(tǒng)的消息隊列如 RabbitMQ 是很大的優(yōu)勢。尤其是在流式處理場景下有天然優(yōu)勢,能夠保證同一隊列的消息被相同的消費者處理,對于批量處理、聚合處理更友好。

消費者消費某個 topic 的消息等同于消費這個 topic 上所有隊列的消息(上圖中 Consumer A1 消費隊列 1,Consumer A2 消費隊列 2、3)。

所以,要保證每個消費者的負(fù)載盡量均衡,也就是要給這些消費者分配相同數(shù)量的隊列,并保證在異常情況下(如客戶端宕機(jī))隊列可以在不同消費者之間遷移。

負(fù)載均衡機(jī)制解析

Cloud Native

負(fù)載均衡時機(jī)

負(fù)載均衡是客戶端與服務(wù)端互相配合的過程,我們先綜合服務(wù)端和客戶端的職責(zé)回答第一個問題:何時會發(fā)生負(fù)載均衡。

客戶端主動負(fù)載均衡


上圖是 RocketMQ 客戶端相關(guān)類的結(jié)構(gòu),其中 MQClientInstance 負(fù)責(zé)和服務(wù)端的交互以及底層服務(wù)的協(xié)調(diào),這其中就包括負(fù)載均衡。

MQClientInstance 中有兩個相關(guān)的方法 rebalanceImmediately 和 doRebalance,我們分析負(fù)載均衡的時機(jī)只要找到何時調(diào)用這兩個方法即可:

啟動時立即進(jìn)行負(fù)載均衡;

定時(默認(rèn) 20s)負(fù)載均衡一次。

服務(wù)端通知負(fù)載均衡


服務(wù)端通知客戶端進(jìn)行負(fù)載均衡也是通過 MQClientInstance#rebalanceImmediately 方法實現(xiàn)的,我們同樣在服務(wù)端代碼中尋找相關(guān)調(diào)用。

分析以上幾個方法可以得出結(jié)論,在如下場景服務(wù)端會主動通知客戶端觸發(fā)負(fù)載均衡:

客戶端上下線

上線

新客戶端發(fā)送心跳到服務(wù)端

下線

客戶端發(fā)送下線請求到服務(wù)端

底層連接異常:響應(yīng) netty channel 的 IDLE/CLOSE/EXCEPTION 事件

2. 訂閱關(guān)系變化:訂閱新 topic 或有舊的 topic 不再訂閱

負(fù)載均衡策略

前文已經(jīng)介紹了負(fù)載均衡實際是變更消費者負(fù)責(zé)處理的隊列數(shù)量,這里每次需要變更的隊列數(shù)量和受到影響的客戶端數(shù)量是由負(fù)載均衡策略決定的。

我們來分析一下比較常見的負(fù)載均衡策略:

平均分配


平均分配(AllocateMessageQueueAveragely)是默認(rèn)的負(fù)載均衡策略:

如果我們有 4 個客戶端,24 個隊列,當(dāng)?shù)诙䝼客戶端下線時:

以默認(rèn)的負(fù)載均衡策略(AllocateMessageQueueAveragely)為例,重新分配隊列數(shù)量為 8。

默認(rèn)的負(fù)載均衡策略能將隊列盡量均衡的分配到每個客戶端,但是每次負(fù)載均衡重新分配隊列數(shù)量較多,尤其是在客戶端數(shù)量很多的場景。

一致性哈希


基于一致性哈希算法的負(fù)載均衡策略(AllocateMessageQueueConsistentHash)每次負(fù)載均衡會重新分配盡可能少的隊列數(shù)量,但是可能會出現(xiàn)負(fù)載不均的情況。

負(fù)載均衡對消費的影響

Cloud Native

我們以一個真實的線上場景來舉例:

下圖中綠色的線代表發(fā)送 tps,黃色的線代表消費 tps,我們很容易發(fā)現(xiàn)在 21:00 和 21:50 分左右存在消費毛刺。

這兩個時間點在進(jìn)行應(yīng)用發(fā)布,根據(jù)我們上文的分析某個消費者下線后同組的其他消費者感知這一變化需要一定時間,導(dǎo)致有秒級的消費延遲產(chǎn)生。在發(fā)布結(jié)束后消費者快速處理堆積的消息,可以發(fā)現(xiàn)消費速度有一個明顯的上漲。

這個例子展示了下線時由于負(fù)載均衡帶來了短暫的消息處理延遲,新的消費者會從服務(wù)端獲取消費位點繼續(xù)之前的消費進(jìn)度。如果消費者異常宕機(jī)或者沒有調(diào)用 shutdown 優(yōu)雅下線,沒有上傳自己的最新消費位點,會使得新分配的消費者重復(fù)消費。

這里我們總結(jié)下負(fù)載均衡對消費的影響,當(dāng)某個客戶端觸發(fā)負(fù)載均衡時:

對于新分配的隊列可能會重復(fù)消費,這也是官方要求消費要做好冪等的原因;

對于不再負(fù)責(zé)的隊列會短時間消費停止,如果原本的消費 TPS 很高或者正好出現(xiàn)生產(chǎn)高峰就會造成消費毛刺。

最佳實踐

Cloud Native

避免頻繁上下線

為了避免負(fù)載均衡的影響應(yīng)該盡量減少客戶端的上下線,同時做好消費冪等。

同時在有應(yīng)用重啟或下線前要調(diào)用 shutdown 方法,這樣服務(wù)端在收到客戶端的下線請求后會通知客戶端及時觸發(fā)負(fù)載均衡,減少消費延遲。

選擇合適的負(fù)載均衡策略

需要根據(jù)業(yè)務(wù)需要靈活選擇負(fù)載均衡策略:

需要保證客戶端的負(fù)載盡可能的均衡:選擇默認(rèn)的平均分配策略;

需要降低應(yīng)用重啟帶來的消費延遲:選擇一致性哈希的分配策略。

當(dāng)然還有其他負(fù)載均衡策略由于時間關(guān)系不一一介紹了,留給讀者自行探索。

RocketMQ 的負(fù)載均衡是每個客戶端獨立進(jìn)行計算,所以務(wù)必要保證每個客戶端的負(fù)載均衡算法和訂閱語句一致。

負(fù)載均衡策略不一致會導(dǎo)致多個客戶端分配到相同隊列或有客戶端分不到隊列;

訂閱語句不一致會導(dǎo)致有消息未能消費。

RocketMQ 5.0 消息級別負(fù)載均衡

Cloud Native

為了徹底解決客戶端負(fù)載均衡導(dǎo)致的重復(fù)消費和消費延遲問題,RocketMQ 5.0 提出了消息級別的負(fù)載均衡機(jī)制。

同一個隊列的消息可以由多個消費者消費,服務(wù)端會確保消息不重不漏的被客戶端消費到:

消息粒度的負(fù)載均衡機(jī)制,是基于內(nèi)部的單條消息確認(rèn)語義實現(xiàn)的。消費者獲取某條消息后,服務(wù)端會將該消息加鎖,保證這條消息對其他消費者不可見,直到該消息消費成功或消費超時。因此,即使多個消費者同時消費同一隊列的消息,服務(wù)端也可保證消息不會被多個消費者重復(fù)消費。

在 4.x 的客戶端中,順序消費的實現(xiàn)強依賴于隊列的分配。RocketMQ 5.0 在消息維度的負(fù)載均衡的基礎(chǔ)上也實現(xiàn)了順序消費的語意:不同消費者處理同一個消息組內(nèi)的消息時,會嚴(yán)格按照先后順序鎖定消息狀態(tài),確保同一消息組的消息串行消費。

如上圖所述,隊列 Queue1 中有 4 條順序消息,這 4 條消息屬于同一消息組 G1,存儲順序由 M1 到 M4。在消費過程中,前面的消息 M1、M2 被 消費者Consumer A1 處理時,只要消費狀態(tài)沒有提交,消費者 A2 是無法并行消費后續(xù)的 M3、M4 消息的,必須等前面的消息提交消費狀態(tài)后才能消費后面的消息。

文章來源:騰訊,如涉及到版權(quán)問題,請聯(lián)系網(wǎng)站管理員刪除!