本文原做者爲Matt Klein,爲envoy的工程師。發表於2017年12月。因原文英文寫做和其它緣由,本人以爲有必要分享。但翻譯後期發現該文已於2018年1月被人翻譯。思考再三,決定發佈本身的翻譯版本。原文較長,我分爲三個部分便於你們閱讀。此爲第一篇算法
負載均衡是構建可靠的分佈式系統所須要的核心概念之一。維基百科將負載均衡定義爲:編程
在計算機中,負載均衡可改善跨越多個計算資源(例如計算機與集羣、網絡連接、中央處理單元(cpu)或磁盤驅動器)的工做負載分配。負載均衡旨在優化資源l利用率,最大化吞吐量,最小化響應時間,並避免任何單點資源過載。經過冗餘機制,使用負載均衡組建能夠提升可靠性和可用性。負載均衡一般涉及專用軟件或硬件,例如多層交換機或域名系統服務進程。後端
以上定義適用於計算機的全部領域(包括網絡)。操做系統使用負載均衡來跨越物理處理器調度任務。容器協調器(如Kubernetes,k8s)使用負載均衡來跨越計算集羣調度任務,網絡負載均衡器使用負載均衡技術來跨越可用後端調度網絡任務。本文僅涵蓋(介紹)網絡負載均衡技術。
圖1 網絡負載均衡概述緩存
圖1描述了網絡負載均衡的核心用途。一些客戶端正在向後端(服務器)請求資源。負載均衡器位於客戶端和後端之間,並執行幾項關鍵任務:安全
客戶端並不須要知道或瞭解負載均衡器代理的後端,由負載均衡器來管理和分配任務給後端(服務發現)。負載均衡經過預約義機制來解決。(預約義機制包括內置庫和衆所周知的DNS / IP /端口)池化,而後能夠將名稱解析行爲委託給負載均衡器。(下文更詳細地討論)。譯註:能夠理解爲VIP+NAT技術處理機制。服務器
經過健康檢查機制和各類算法技術,負載均衡器能夠有效地屏蔽故障或系統過載的後端(譯註: 在資源池中掛起或剔除)。這意味着系統(網絡)管理員一般能夠在空閒時修復異常的後端,而無需緊急處理故障後端。cookie
分佈式系統網絡不多是同質的(即複雜多變)。該系統可能跨越多個網段和區域。在一個區域內,網絡流量相對寬鬆。而在另外一個區域內,超額認購(流量超標)成爲常態。(這裏,網絡過載或空餘是指經過網卡消耗的帶寬數量佔不一樣路由器間的可用帶寬的百分比)。智能負載均衡儘量地保持一個區域內的請求流量,從而提升性能(減小延遲)並下降總體系統成本(區域之間所需的帶寬和光纖更少)。譯註:後端A在X區,帶寬100M,後端B在Y區,帶寬1000M。網絡
按照當前業界分類,負載均衡一般根據OSI模型分爲4層和7層負載。簡稱L4&&L7。但這種分類並不許確。例如L4負載均衡也支持TLS termination,那麼它屬於L4仍是L7負載設備呢?不過,咱們無需刻意較真,目前仍然按照當前流行的分類繼續討論。本文中,負載均衡與代理在用途上理解爲等同的。可能有些人會爭辯說,當負載均衡做爲嵌入式客戶端庫的一部分時負載均衡器實際上並不是用於代理功能。可是,我認爲這種區分會給已經使人困惑的話題帶來沒必要要的複雜性。負載均衡器拓撲的類型將在下面詳細討論,這篇文章將嵌入式負載均衡器拓撲視爲代理的特殊狀況; 應用程序經過嵌入式庫進行代理,該庫提供了應用程序進程以外的負載均衡器相同的抽象。架構
圖2:TCP L4終端負載均衡負載均衡
圖2顯示了傳統的L4 TCP負載均衡器。在這種狀況下,客戶端與負載均衡器創建TCP鏈接。負載均衡器直接響應SYN,而後選擇後端應答,並與後端創建新的TCP鏈接(即發送新的SYN)。該圖的細節並不重要,將在下面專門討論L4負載平衡的部分中詳細討論。這裏的關鍵點是L4負載均衡器一般僅在L4 TCP / UDP層 (鏈接/會話)級別運行。所以,負載均衡器在先後端分別傳輸數據,並確保同一會話的數據在同一後端結束。L4負載均衡器不知道(關心)數據的具體內容。這些數據能夠是HTTP,Redis,MongoDB或任何其餘應用程序協議。
L4負載均衡因邏輯簡單被普遍使用。那麼是否是L4負載平衡就知足全部需求了?當時不是,L7(應用程序)負載平衡用於處理L4不具有的功能,如下面L4特定案例爲例:
兩個GRPC 和 HTTP2客戶端但願經過一個L4負載均衡器鏈接與後端通訊。
L4負載均衡器爲每一個傳入的TCP鏈接創建單個傳出TCP鏈接,從而產生兩個傳入和兩個傳出鏈接。即會話不可複用。資源消耗較高。
然而,客戶端A經過其鏈接每分鐘發送1個請求(RPM),而客戶端B經過其鏈接發送每秒50個請求(RPS)。
這時候,選擇處理客戶端A的後端將處理比選擇處理客戶端B的後端大約少3000倍的負載。這種問題顯然破壞了負載均衡存在的意義。還要注意,這個問題發生在多路複用、會話保持(長鏈接)時產生的影響。(多路複用意味着經過單個L4鏈接、發送並行應用程序請求。而會話保持意味着在沒有活動請求時不關閉鏈接)。全部現代協議(新應用)爲提升效率都在支持多路複用和會話保持(建立鏈接成本很高,特別是當使用TLS加密鏈接時),所以L4負載均衡處理明顯不足。此問題均由L7負載均衡器來解決。
圖3:HTTP/2 L7終端負載均衡
圖3顯示了L7 HTTP / 2負載均衡器。在這種狀況下,客戶端(client)與負載均衡器(Load balancer)創建單個HTTP / 2 TCP鏈接。而後負載均衡器與兩個後端創建鏈接。當客戶端向負載均衡器發送兩個HTTP / 2請求數據時,請求數據流1被髮送到後端1(backend1),請求數據流2被髮送到後端2(backend2).所以,即便多路複用具備大相徑庭的請求,負載響應客戶端後也將在後端進行有效地均衡分配。這就是L7負載平衡對現代協議如此重要的緣由。(L7負載均衡因爲可以檢查應用程序流量而產生巨大的額外優點,將在下面詳細介紹)。
如前文所述,使用OSI模型來描述和歸類負載均衡功能是有問題的。緣由是L7,至少如OSI模型所描述的那樣,自己包含多個離散的負載均衡抽象層。例如,對於HTTP協議的流量,請考慮如下子層:
在本節中,我將簡要總結負載均衡器提供的高級功能。但並不是全部負載均衡器(譯註:具體到某軟硬件如F5,NGINX)都提供全部功能。
服務發現是負載均衡器肯定可用後端集的過程。方法多種多樣,一些例子包括:
健康檢查是負載均衡器肯定後端是否可用並分配資源的過程。健康檢查一般分爲兩類:
是的,負載均衡器必須真實平衡負載!提供一組健康的後端,如何選擇後端來提供鏈接或請求?要依靠負載均衡核心算法。從簡單的算法:如隨機選擇和循環(輪詢、加權輪詢),到考慮可變延遲和後端負載分析的更復雜算法。考慮到其性能和簡單性,最受歡迎的負載平衡算法之一被稱爲2個最小請求負載平衡功能。
某些應用程序(業務場景),同一會話的請求到達相同的後端很是重要。這可能與緩存,臨時複雜構造狀態等有關。會話的定義各不相同,可能包括HTTP cookie,客戶端鏈接的屬性或其餘屬性等。許多L7負載均衡器都支持粘性會話。值得一提的是,粘性會話本質上很脆弱(被託管會話的後端可能會宕機),所以在設計依賴它們的系統時要當心。
譯註:典型L7負載的會話保持功能。
TLS的主題及其在邊界服務和保護服務到服務通訊中的做用值得一提。聽說,許多L7負載均衡器進行大量的TLS處理,包括終止,證書驗證和一致性,使用SNI的證書服務等。
網絡本質上是不可靠的,負載均衡器一般須要負責導出統計數據,跟蹤和輸出日誌,幫助分析人員找出問題所在,以便他們可以解決問題。負載均衡器的可觀察性輸出差別很大。最早進的負載均衡器提供豐富的輸出,包括數字統計,分佈式跟蹤和可自定義的日誌記錄。須要指出的是,可視化數據越豐富, 負載均衡器就必須消耗本身的部分資源來完成其工做。若是數據輸出(展現)的好處大大超過了相對較小的性能損失,那麼是值得的。
尤爲是在邊界部署拓撲(見下文),負載均衡器一般實現的各類安全功能,包括速率限制,認證和DoS防護(例如,IP地址標記和識別,tarpitting(過濾)等)。
配置和控制面板
在大型項目的部署和實施中,配置負載均衡器,這可能成爲一項重大任務。一般,配置負載平衡器的系統稱爲「控制面板」,而且在其實現中變化很大。
負載均衡器拓撲的類型
圖4:中間代理負載均衡拓撲
圖4中所示的中間代理拓撲可能負載均衡最經常使用的方法。此類別包括Cisco,Juniper,F5等硬件設備; 亞馬遜的ALB和NLB以及谷歌的雲負載均衡器等雲軟件解決方案; 和純軟件自託管解決方案,如HAProxy,NGINX和Envoy。中間代理解決方案好處使用方便。一般,用戶經過DNS(譯註:或者配置VIP)鏈接到負載均衡器,無需擔憂其餘任何問題。中間代理解決方案的缺點是代理(即便是羣集)是單點故障,還有擴展瓶頸問題。中間代理一般也是黑盒模式,使維護變得困難。一旦出現問題,故障是否在客戶端?在物理網絡?在中間代理負載均衡自己?甚至在後端?這很難說。
圖5:邊界代理負載均衡拓撲
邊界代理拓撲如圖5所示,實際上只是中間代理拓撲的一種變體,能夠經過Internet訪問負載均衡器。在這種狀況下,負載均衡器一般必須提供額外的「API網關」功能,例如TLS終端,速率限制,身份驗證和複雜的流量路由。邊界代理的優缺點與中間代理相同。須要注意的是,在面向Internet的大型分佈式系統中部署專用邊界代理一般是不可避免的。客戶端一般須要使用服務全部者沒法控制的任意網絡(一般指互聯網)經過DNS訪問系統(如下部分中描述的嵌入式客戶端庫或跨斗車代理拓撲不能直接在客戶端上運行)。另外,爲了安全因素設置一個單獨的安全網關是必要的,全部面向互聯網的流量都必須先通過這個安全網關才能進入系統。如防火牆
圖6:經過嵌入式客戶端庫進行負載均衡
爲了不中間代理拓撲中固有的單點故障和擴展問題,複雜的基礎架構已經轉向將負載均衡器經過庫直接嵌入到服務中,如圖6所示。在支持的特徵中,庫差異很大,但在這一類中最爲人熟知和特徵豐富的產品是Finagle,Eureka / Ribbon / Hystrix和gRPC(基於一個Google內部稱做Stubby的系統)。基於庫的解決方案的主要優點在於它將負載均衡器的全部功能徹底分配給每一個客戶端,從而消除了以前描述的單點故障和擴展問題。基於庫的解決方案的主要缺點是庫必須以項目組織使用的每種語言實現。分佈式架構正變得愈來愈「多語言」。在這種環境下,以多種不一樣語言從新實現極其複雜的網絡庫的成本可能會變得使人望而卻步。最後,在大型服務架構中部署庫升級可能會很是痛苦,所以頗有可能在生產中同時運行庫的許多不一樣版本。
譯註: Sidecar-中文爲(摩托車的)跨鬥。以下圖
圖7:經過sidecar代理進行負載均衡
嵌入式客戶端庫負載均衡器拓撲的變體是圖7中所示的挎斗車代理拓撲。近年來,這種拓撲結構已經被普及爲「服務網格」。挎斗車代理背後的想法是,經過跳轉到不一樣的進程而致使輕微的延遲損失,嵌入式方法的好處是在沒有任何編程語言鎖定的狀況下得到。最受歡迎的挎斗車代理負載均衡器是Envoy,NGINX,HAProxy和Linkerd。
不一樣負載均衡器拓撲的總結和優缺點
未完,待續