国产不卡一区二区三区在线_日韩黄色毛片成人免费观看_观看在线人成电影大全_深夜国产福利一区_麻豆91啪啪视频_AA丁香综合激情_午夜福利院国产精品欧美一区_日韩三级黄色毛片_无码中文高清影视_亚洲色大成网址在线观看

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

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

2023/1/7 22:14:35      點(diǎn)擊:

前言

Cloud Native

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

負(fù)載均衡意義

Cloud Native

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

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

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

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

Cloud Native

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

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

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


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

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

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

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

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


服務(wù)端通知客戶端進(jìn)行負(fù)載均衡也是通過 MQClientInstance#rebalanceImmediately 方法實(shí)現(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ù)載均衡實(shí)際是變更消費(fèi)者負(fù)責(zé)處理的隊(duì)列數(shù)量,這里每次需要變更的隊(duì)列數(shù)量和受到影響的客戶端數(shù)量是由負(fù)載均衡策略決定的。

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

平均分配


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

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

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

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

一致性哈希


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

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

Cloud Native

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

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

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

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

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

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

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

最佳實(shí)踐

Cloud Native

避免頻繁上下線

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

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

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

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

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

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

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

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

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

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

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

Cloud Native

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

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

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

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

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

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