本文介紹了 Twitter 在客户端負載均衡技術方面的實踐,以犧牲中心化控制為代價,構建更高性能的負載均衡系統。原文:Client-Side Load Balancing: Concepts, Benefits & Practical Uses
當我們運行數千後端服務時,即使路由上的一個小延遲也會減慢所有服務的速度。客户端負載均衡將路由決策從中間層轉移到客户端,從而減少開銷並提高了速度。Twitter 就採用了這種模式,從而滿足業務需求,避免路由瓶頸。我們來看看這種模式是如何工作的,以及為什麼重要。
什麼是客户端負載均衡?
傳統負載均衡依賴於中央路由器,這個中間層會接收每一個客户端請求,並將其轉發到後端服務器。路由器是整個路徑中的關鍵部分。
客户端負載均衡消除了這一額外傳輸環節。每個客户端都會收到一份可用後端服務器列表,將這份列表存儲在本地,並據此決定將請求發送至何處。這使得路由過程更快、更可靠,也更易於擴展。
不再是由一台路由器獨自承擔所有工作,而是每個客户端都分擔相應的任務。
客户端負載均衡的優勢
- 降低延時
請求直接從客户端發送至服務器,無需經過中央路由器,從而避免因路由器而產生的延遲問題。
- 無單點故障
如果某個客户端出現問題,其他客户端仍能繼續正常工作。整個系統不存在可能導致整體崩潰情況的單一關鍵節點。
- 更優的流量分配
每個客户端都會自行分配流量,將負載均勻分配到所有服務器上。
- 本地控制
客户端會根據實時反饋做出路由決策,可以迅速重試,也可以在必要時暫停操作。
- 易於擴展
隨着服務增多,添加新的客户端或服務器並不會使中央路由器不堪重負,該系統能夠自然的進行擴展。
Twitter 如何使用客户端負載均衡
Twitter 使用名為 Finagle 的庫來管理服務之間的通信。此外還構建了名為 Aperture 的客户端負載均衡器。該系統能夠處理跨數千微服務的請求路由。
Aperture 利用一組虛擬服務器,為每個客户端分配一小塊區域。這種方法有助於 Twitter 保持請求路由的快速且公平性。隨着時間推移,Twitter 對四種不同的 Aperture 系統進行了試驗。
Aperture 類型
| 類型 | 描述 |
|---|---|
| Mesh topology
網狀拓撲 |
客户端與所有服務器建立連接。適用於小規模部署,但無法橫向擴展。 |
| Random aperture
隨機孔徑 |
每個客户端隨機挑選一部分服務器。實現簡單,但可能導致負載不均。 |
| Deterministic-Discrete ring
確定性離散環 |
服務器被劃分為固定槽位,每個客户端通過哈希獲得一個穩定的窗口。高效。 |
| Deterministic-Continuous ring
確定性連續環 |
服務器在哈希空間中連續映射,窗口可動態調整。靈活,但實現更復雜。 |
- Mesh topology(網狀拓撲)
在網狀架構中,每個客户端都與每個服務器建立連接。這種方式能提供最大的可見性,但連接成本很高。
- 在小型系統中運行良好
- 但在大型集羣中無法擴展
- 存在過多的開放連接和過高的內存使用量
Twitter 很早就摒棄了這種設計。
- **Random aperture(隨機孔徑)
每個客户端都會隨機連接到後端服務器的一組子集。
- 易於實施
- 減少連接數量
- 但隨機性可能會導致不均衡。一些客户端可能會連接到較慢的服務器。
- 確定性孔徑 —— 離散環結構
這是 Twitter 最常用的方法。服務器以固定的環形排列方式佈置,每個服務器根據一致性哈希獲得固定位置。
- 客户端獲得固定大小的窗口(即 aperture),進入環形區域
- 窗口基於客户端 ID 設定,因此是穩定的
- 請求會被均勻且可預測的分發
如果需要,窗口大小可根據流量情況進行擴大或縮小,從而在不使服務器過載的情況下更易於管理負載。
- 確定性孔徑 —— 連續環結構
此版本採用連續哈希空間(類似於從 0 到 1 的一個圓環)。服務器根據權重或容量被映射到該空間中。
- 客户端從哈希環中選擇分段
- 適用於服務器負載變化的情況
- 更具靈活性,但稍微複雜一些
無論是離散環還是連續環,都能提供強大的控制功能,能幫助 Twitter 在數百萬次請求中管理延遲和公平性。
實際運作方式
客户端會記錄每次請求所花費的時間。如果延遲增加或隊列變長,就會擴大窗口大小,連接更多服務器。如果流量減少,就會縮小窗口大小。
在該窗口(Aperture)內,Twitter 採用二進制冪次選擇(P2C)的方式來選定服務器:
- 從該窗口中隨機選取兩個服務器
- 將請求發送至當前待處理請求較少的那個服務器
這種方法簡單卻有效,能夠避免熱點問題,並保證響應時間。
另一個用例:Lyft 的 Envoy
Lyft 採用 Envoy(一款開源邊緣和服務代理工具),運行在每個服務內部,並負責處理客户端的路由。
與 Twitter 類似,Envoy 也從服務發現工具中獲取到一組可用後端服務器列表,決定將流量發送至何處,重試失敗的請求,並在本地記錄指標數據。
這使得 Lyft 能夠對流量進行精細控制,同時又能避免路由器過載。該架構有助於 Lyft 在數千個容器之間實現擴展。
客户端負載均衡的缺點
- 服務器列表過時:如果後端服務器崩潰,某些客户端可能不會立即察覺。
- 客户端複雜度增加:客户端必須處理路由邏輯、重試和延遲策略,增加了代碼量和責任。
- 全局意識降低:每個客户端只能看到系統部分區域,可能會錯過更廣泛的趨勢,比如全球負載分佈不均。
- 內存使用量更高(在某些設計中):網狀結構或大型窗口可能需要打開大量連接。
總結
客户端負載均衡以集中控制為代價換取速度和靈活性。Twitter 的 Aperture 系統使用智能算法和穩定的環形結構實現低延遲路由流量。其他公司,如 Lyft,也採用了類似設計。雖然這種方法增加了客户端複雜性,但消除了中心化瓶頸,在大規模應用中會產生巨大影響。
你好,我是俞凡,在Motorola做過研發,現在在Mavenir做技術工作,對通信、網絡、後端架構、雲原生、DevOps、CICD、區塊鏈、AI等技術始終保持着濃厚的興趣,平時喜歡閲讀、思考,相信持續學習、終身成長,歡迎一起交流學習。為了方便大家以後能第一時間看到文章,請朋友們關注公眾號"DeepNoMind",並設個星標吧,如果能一鍵三連(轉發、點贊、在看),則能給我帶來更多的支持和動力,激勵我持續寫下去,和大家共同成長進步!
本文由mdnice多平台發佈