Categories
程式開發

Talos網卡負載優化:基於個性化一致性哈希的負載均衡


在《萬億級消息背後: 小米消息隊列的實踐》文章中介紹了小米自研消息隊列Talos的業務背景和關鍵問題。

其中在網卡資源優化方面,Talos主要做了兩方面工作:客戶端尋址與基於流量的個性化一致性哈希。前者是通過客戶端自尋址避免Server轉發節省網卡資源,後者是通過優化一致性哈希的虛擬節點數配置,調整節點的流量分配情況。

本文將詳細介紹後者——基於個性化一致性哈希的流量均衡方法。

業務增長帶來的流量均衡需求

Talos作為高吞吐型的消息隊列服務,隨著業務增長,帶寬往往會成為瓶頸。如果網卡流量不均衡,就會產生集群網卡資源的木桶效應—— 當集群中使用網卡最多的機器達到資源瓶頸就要觸發擴容,即便此時該集群其他節點網卡有大量富餘,機器成本因此浪費。且隨著業務量越來越多,集群規模不斷變大,問題變得更加明顯。

以小米某線上集群為例,該集群150台機器,將各節點的日流量均值繪製成散點圖以方便觀察其流量均衡程度。其中最高流量324M,最低134M,相差兩倍不止。

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 1

分析此問題,機器節點網卡流量的大小,和該節點所serve的所有Partition流量之和呈正相關。要解決節點間網卡負載不均衡的問題,需要調整Partition在各節點的分佈情況(即改變Partition的調度關係)。下面我們將簡單介紹下優化前Talos所使用的調度機制,再來分析如何做到這一點。

基於一致性哈希的調度策略

Talos使用一致性哈希來約定Partition調度關係。簡單來講,一致性哈希可以理解為一個函數,Y = ConsistentHash (X)。任意的X取值都能映射為一個固定區間內的唯一數值Y.

舉例說明,我們將10節點集群中各節點做映射,用下面的環狀圖表示。那麼區間被分成了10份。同樣將Partition映射也映射到環上,根據其位置區間,來決定由哪個節點所serve. 集群所有節點都遵從這個約定從而調度信息一致。

實際上,為了使圓環劃分的更加均勻和節點上下線更加穩定,每個機器節點將對應多個虛擬節點以力求平均。傳統的一致性哈希,每個節點映射的虛擬節點個數是一致的。例如,Talos每個機器節點對應的虛擬節點個數都是2000個。

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 2

可以理解,使用一致性哈希的調度方式,力求的是Partition個數分佈的盡量均衡,各Partition在調度中的權重是一樣的,並不關心Partition其他指標(例如QPS和流量)的差異,且一致性哈希算法的映射關係我們無法干預和調節。

個性化一致性哈希的流量均衡

想要解決這個問題,我們需要引入流量信息參與Partition調度決策。通過在調度策略中引入流量反饋機制,調節一致性哈希虛擬節點個數,達到流量均衡。

具體思路是,獲得監控數據,對比節點的流量值與集群各節點流量均值。如果該節點流量值較大,則通過減少該節點的虛擬節點個數減少所serve的Partition個數;如果該節點流量值較小,則通過增多該節點的虛擬節點個數增多所serve的Partition個數,不斷反饋。可以用下圖表示。

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 3

通過監控反饋和虛擬節點不斷的調整,該方式最終可以找到符合各節點流量均衡分佈的一致性哈希虛擬節點分佈,下圖簡單解釋下優化調度效果。

優化前的調度:Partition個數大致均勻

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 4

優化後的調度:節點流量均勻

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 5

相比於引入一個中心節點來實現統一的定制的調度機制,這種方式對Talos原有架構來說改動較小,且不會引入複雜的中心節點可用性問題。

流量均衡在Talos中的實現

依據上述思想落地到Talos業務,需要考慮穩定性問題,分析影響穩定性的因素:

  • 對Talos來說,Partition在節點間的遷移大約在7s左右可恢復服務。由於流量均衡過程中會產生Partition的遷移,如果短時間內大規模的Partition遷移,由於資源的集中調用,不僅會造成恢復時間增長,大規模的遷移還可能帶來集群可用性抖動。

  • 類似HDFS Balance,我們可以設定流量均衡的目標值,例如,設定目標值為10%,則目標是調整集群最大日均流量與最小日均流量在集群日均流量的10%範圍內。有些情況下某些目標值我們是無法達到的,這時的調整最終就會變成來回震蕩的狀況。舉個最簡單的例子,A​​機器100M流量,B機器50M流量,單個Partition的流量值是50M,按照10%的目標去調整,結果就是會在A 50M and B 100M和A 100M and B 50M的情況之間來回震盪。不僅達不到目標,還白白帶來遷移開銷。

  • 還有一些情況,會出現“往壞的方向調節”。依然以一個簡單例子說明,A機器100M流量,B機器80M流量,調整目標10%,單個Partition的流量值是50M,一次調節後變成A 50M而B 130M,均衡度更差。 2和3問題的出現​​,本質上都是由於我們調節的最小粒度是Partition。

為了避免這些問題,設定了以下機制:

  • 通過監控數據模擬計算,模擬符合預期才觸發調整。取得各Partition的流量監控數據,帶入一致性哈希函數,模擬調整虛擬節點個數併計算各節點流量值;

  • 控制每次遷移的Partition個數,保證集群整體穩定性;

  • 計算方差決定是否調整,以防止無謂的震盪調整或往更壞的方向調整。方差能反應離散程度,只有當模擬調整後的方差變小才觸發調整;

  • 設定最大調節次數,以設定調整目標無法達到時的無限模擬計算。

最終的實現架構如下:

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 6

其中BalanceServer會負責完成根據閾值和監控值模擬計算,控制遷移量,按規定時間間隔觸發等邏輯。集群的可用性不依賴BalanceServer,BalanceServer掛掉只是停止了集群的流量均衡調整,集群會繼續按照當前的虛擬節點分佈進行調度運行,即便出現了集群節點上下線也沒關係。

接下來展示下集群均衡的效果,依然以文章開頭展示流量圖的Talos集群為例,將調整後各節點的日流量均值製作成散點圖,可以發現優化後各節點流量值明顯聚合。經計算,此集群150台機器,可節省因網卡達到瓶頸而需要擴容的機器35台。

Talos網卡負載優化:基於個性化一致性哈希的負載均衡 7

值得借鑒的是,通過改變BalanceServer引入的監控參數,此方法可以擴展到基於一致性哈希的分佈式系統的QPS均衡、甚至CPU資源和內存資源均衡,只要找到本系統監控指標和均衡指標間的函數關係即可。

相關閱讀:

消息隊列在企業架構中扮演著什麼角色?

萬億級消息背後: 小米消息隊列的實踐