1. 程式人生 > >微信後臺異步消息隊列的優化升級實踐分享

微信後臺異步消息隊列的優化升級實踐分享

2.0 ref 所有 處理 轉載 tps 訪問量 成功 class

1、引言

MQ 異步消息隊列是微信後臺自研的重要組件,廣泛應用在各種業務場景中,為業務提供解耦、緩沖、異步化等能力。本文分享了該組件2.0版本的功能特點及優化實踐,希望能為類似業務(比如移動端IM系統等)的消息隊列設計提供一定的參考。

2、關於分享者

廖文鑫,2013年加入騰訊,從事微信後臺基礎功能及架構的開發和運營,先後參與了消息通知推送系統、任務隊列組件、春晚搖紅包活動等項目,在海量分布式高性能系統方面有豐富的經驗。

3、背景介紹

微信後臺給件 MQ 1.0 發布之初,基本滿足了一般業務場景的異步化需求,實現了單機下高性能的任務持久化和消費調度。

MQ 1.0 的基本框架如下圖所示:

技術分享

可以看到,其主要分為 MQ 和 Worker 兩部分。MQ 是任務的持久化和調度框架,Worker 是任務的處理框架。

該組件與常見的隊列相比,有幾個特點:

  • 關註單機性能,任務單機持久化,本機消費;
  • 框架介入了任務的整個生命周期,其中包括了:入隊落盤、派發、處理、提交結果、銷毀。業務基於框架開發,專註任務的處理邏輯。


隨著業務發展,面對日益復雜的業務場景,1.0 版本逐漸顯得力不從心。因此,在 1.0 的基礎上,我們實現了 MQ 2.0 版本,主要優化點包括以下幾方面:

  • 更優的任務調度;
  • 更高效的任務處理;
  • 更強的過載保護。


下面對各個優化點詳細講解。

4、需要實現更優的任務調度

(1)現狀分析

iOS消息通知功能,是MQ組件的一個典型應用場景。微信的後臺具有多IDC分布的特點,不同IDC與蘋果推送服務(APNs)之間的網絡質量參差不齊,部分鏈路故障頻發。

技術分享

由於MQ 1.0 的任務只能本機消費,網絡質量的下降將直接導致 Worker 消費能力的下降,進而產生積壓,最終使消息服務質量受損。

為此,我們提出了跨機消費模式。其目標是實現一個去中心化、自適應的彈性消費網絡,以解決系統中出現的局部積壓問題。

(2)任務調度是跨機消費的核心問題


消費模式從單機擴展到多機後,我們要面臨的核心問題是,哪些任務給哪個 Worker 去處理。其實,考慮多機房、多IDC、帶寬成本、任務延時等因素,我們很容易得到一個直觀而樸素的思想:任務優先在本機消費,產生積壓時才發生跨機消費



如何實現我們想要的跨機消費呢?經過思考,我們將問題分解為三個子問題:

  • 拉任務還是推任務?
  • Worker 如何感知 MQ 的積壓?
  • Worker 如何消除 MQ 的積壓?


下面逐一進行討論。

(3)拉任務還是推任務


MQ 1.0 下,MQ 可以準確觀察到本機 Worker 的負載狀態,並由其將任務推送給空閑的 Worker 進行處理。推送的方式可以將任務的處理延時做到極低。

擴展到跨機消費後,Worker 可以消費任意 MQ 的任務。對 MQ 而言,已經難以精確地維護全網每個 Worker 的狀態了。若繼續沿用推任務的方式,很可能會出現 Worker 接收到超過其處理能力的任務量,從而產生積壓。

若使用 Worker 拉取任務的方式,則拉取的速度可以根據 Worker 自身的消費能力調整,但在任務延時上,需要有所犧牲。

推任務:優點,低延時;缺點,任務在 Worker 端積壓,無法被重新調度;
拉任務:優點,任務在 MQ 端積壓,可以被空閑的 Worker 拉走;缺點,延時稍高。

經過簡單的權衡,我們選用了拉任務的方式,畢竟,我們難以接受任務積壓在 Worker 側的情況。

(4)Worker 如何感知 MQ 的積壓

前面提到,系統應該在任務出現積壓時,才產生跨機消費。因此,MQ 在產生積壓時,應該要能以某種形式通知 Worker。

同時,積壓量的變化是很快的,通知的方式應該做到以下幾方面的高效:

  • 速度:盡可能地快;
  • 精度:盡可能少地發送通知,減少無效通知的發送。


為此,我們實現了廣播模式,將 MQ 產生的積壓量信息作為一個消息,廣播給 多個Worker。

技術分享

它在實現上如何滿足高效的積壓通知要求呢?

  • 速度:使用長連接將積壓量信息推送到 Worker 端;
  • 精度:通過靈活的訂閱過濾器,實現對本機、跨機、跨IDC的分級的廣播。


通過廣播模式,我們高效地解決了 MQ 積壓的感知問題。

(5)Worker 如何消除 MQ 的積壓

通過廣播模式,每個Worker 都可以觀察到所有它感興趣的 MQ 的積壓情況,並以此構建出整個系統的積壓分布統計。拿到這些信息後,Worker 如何決定拉取哪個 MQ 的任務呢?

還是回到我們的原始訴求,盡量做到本機消費。所以我們的策略是說,Worker 應該優先消除本機的積壓,當它有余力的時候,才去幫助其它Worker。

技術分享

通過分優先級地拉取,既可在隊列系統正常時大量降低跨機消費,同時也可以在故障發生時,有效地消除局部積壓。

(6)負載均衡分析

跨機消費模式,從整個系統角度來看,是完全去中心化的,任意一個 MQ 和 Worker 個體都可以獨立、自由地加入或退出系統。

技術分享

在這個競爭式的消費系統裏,根據具體的部署情況、不同機型消費能力不同等因素,無法達到完全的負載均衡狀態。但在系統產生局部過載時,則可以自適應調節,達到相對的均衡。

(7)小結

從實際應用效果來看,MQ 2.0實現了通知推送服務的IDC級別容災,即使只剩下一個IDC可用,也可以做到推送質量紋絲不動。

MQ 2.0 對跨機消費模式的支持,為業務提供了一種新的隊列容災模式:

  • MQ 與 Worker 可完全分離部署,分別規劃機器數量,按需部署,互不影響;
  • MQ 的局部積壓可以通過擴容 Worker進行消除;
  • Worker 的局部消費能力下降可以由其它 Worker 自動容災。

5、需要實現更高效的任務處理

(1)現狀分析

微信發布已有6年多的時間,後臺的業務邏輯演化至今,往往是非常的復雜,我們來看一個比較極端的例子 —— 群聊批量並行化投遞

技術分享

上圖是群消息投遞業務的簡化流程示意。隨著微信群消息體量的高速膨脹,其帶來的成本壓力越來越大,業務同學提出了批量並行化的優化方式。簡單來說,就是將每個步驟中產生的 RPC 訪問按實際訪問機器聚合成一系列的批量操作,然後並行化執行。

通常來說,單次的批量並行化並不難寫,一般而言,業務同學可能會選擇裸寫。但如果涉及多次的批量並行化,其中還存在嵌套的話,事情就不那麽簡單了。最終代碼將變得異常復雜,業務開發的同學苦不堪言。MQ 能否從框架上解決這類問題?

(2)類 MapReduce 任務處理框架


其實,深入分析群消息投遞的優化需求,可以看到:

  • 一次批量並行化操作本質上是一次 MapReduce 過程;
  • 整個群消息投遞的處理過程是多次 MapReduce 過程的串聯和並聯。


所以,為了從根本上解決這一類問題,MQ 為業務提供了類 MapReduce 任務處理框架。

技術分享

該框架提供封裝了通用的 MapReduce 過程,以及並發的調度過程,同時提供並發池隔離能力,解決了並發池餓死的問題。讓業務同學可以從冗繁的代碼中解放出來,將更多的精力投入到實際業務中。

(3)流式任務處理框架


除了批量並行化的需求,業務經常提到的一個需求是,任務處理時會產生一些新的任務需要加到隊列中。一般來說是走一次 RPC 來執行任務入隊。在 MQ 2.0 下,流式任務可以幫忙完成這個事情。

所謂流式任務,就是在任務處理結束時,除了返回任務結果,還可以返回一系列新的任務。這些任務通過 MQ 內部框架流轉入隊,更輕量,事務性更強。

技術分享

(4)小結

MQ 2.0 提供的類 MapReduce任務處理框架和流式任務處理框架,為業務的實現提供了便利的支持。

6、需要實現更強的過載保護

(1)現狀分析

MQ的重要作用是充當系統中的緩沖節點,流量控制的能力是非常關鍵的。在 MQ 1.0 下,只能通過配置隊列的任務出隊速度來實現流量控制。

其問題有幾個:

  • 配置需要人工調整,難以估算對後端的實際訪問;
  • 後端處於過載狀態時無法自適應調整;
  • 自己處於過載狀態時無法自適應調整

(2)問題分析


從需求來看,MQ 的過載保護需求有兩個方面,一是保護自己不過載,二是保護後端不過載。

導致過載的因素很多,從 MQ 的角度來看,這些因素可以分為兩大類。一種是它能直接觀察的因素,如自身的 CPU 使用率,內存使用率,任務執行的成功率;另一種是無法直接觀察的因素,如業務實際對後端產生的調用量。

從這兩類因素出發,我們將過載保護的策略分為兩大策略:

  • 前向限速:MQ 通過其直接觀察到的數據,主動對任務派發進行限速;
  • 後向限速:MQ 通過業務反饋的數據,被動對任務派發進行限速。


下面分別討論兩種策略。

(3)前向限速

基於 CPU 使用率的流控:
該限速策略很好理解,就是在 CPU 使用率過高時,降低任務處理速度,以將 CPU 資源優先用於保證隊列的緩存

技術分享

基於任務成功率的流控:
後端模塊故障時,往往會導致隊列任務出現大量的失敗和重試,這些重試的量級往往會遠超該後端模塊設計的有效輸出,給故障恢復帶來很大的困難。該流控策略的通過收集任務執行的成功率信息,評估後端的有效輸出,並通過反饋計算限制任務重試的速度。

技術分享

(4)後向限速

MQ 實現了通用的後向限速能力,業務通過特定接口往 MQ 回傳控制量,達到速度調控的目的。

基於後端 RPC 訪問量的流控:
我們經常會遇到一些業務在處理任務時,存在不同程度的對後端的擴散訪問。僅對任務處理速度進行限制,無法準確限制對後端產生的實際調用量。該策略通過收集業務對後端產生的實際調用量,反向調節任務處理的速度。

技術分享

(5)小結

MQ 2.0 通過分析流控需求,在前向和後向分別提供了有效的流控手段,並且為後續更精細的流控策略預留了拓展的能力,增強了過載保護的能力。

十分感謝微信團隊的編寫,本文僅為轉載,留個記錄。原文地址:微信後臺團隊:微信後臺異步消息隊列的優化升級實踐分享

微信後臺異步消息隊列的優化升級實踐分享