您好,登錄后才能下訂單哦!
下文給大家帶來關于負載均衡那點事兒的一些淺見,希望能夠給大家在實際運用中帶來一定的幫助,負載均衡涉及的東西比較多,理論也不多,網上有很多書籍,今天我們就用億速云在行業內累計的經驗來做一個解答。
網絡負載均衡和代理是什么?
Wikipedia 對負載均衡的定義 是:
In computing, load balancing improves the distribution of workloads across multiple computing resources, such as computers, a computer cluster, network links, central processing units, or disk drives. Load balancing aims to optimize resource use, maximize throughput, minimize response time, and avoid overload of any single resource. Using multiple components with load balancing instead of a single component may increase reliability and availability through redundancy. Load balancing usually involves dedicated software or hardware, such as a multilayer switch or a Domain Name System server process.
中文版:
負載平衡(Load balancing)是一種計算機網絡技術,用來在多個計算機(計算機集群)、網絡連接、CPU、磁盤驅動器或其他資源中分配負載,以達到最優化資源使用、最大化吞吐率、最小化響應時間、同時避免過載的目的。使用帶有負載平衡的多個云服務器組件,取代單一的組件,可以通過冗余提高可靠性。負載平衡服務通常是由專用軟件和硬件來完成。
上面的定義不僅包含了網絡,還包含了計算的所有方面。操作系統、網絡以及容器編排器等都有各自的負載均衡技術,用于使用各自的資源進行各自的任務調度。本文僅就網絡負載均衡進行探討。
1:網絡負載均衡概覽
對網絡負載均衡進行了一個高層次的概括。多個客戶端向多個后端發起資源請求,負載均衡器處于客戶端和后端之間,簡單來說完成如下任務:
服務發現:系統中有哪些后端可用?這些后端的地址(也就是:負載均衡器如何同這些后端通信)?
健康檢查:哪些后端是健康的可以用于接收請求?
負載均衡:用什么算法來把獨立的請求分發給健康的后端?
在分布式系統中合理的使用負載均衡能帶來很多好處:
命名抽象:每個客戶端不再需要知道每一個后端(服務發現),客戶端可以通過預定義的機制來找到負載均衡器,然后讓負載均衡器完成命名解析功能。這些機制包括內置庫,以及路人皆知的 DNS/IP/端口 地址,后面會深入討論。
錯誤隔離:通過健康檢查以及一些其他的算法和技術,負載均衡器的路由方法能夠有效的繞過癱瘓或過載的后端。這樣運維人員在面對系統故障時,就可以更加從容的進行錯誤處理。
成本和性能收益:分布式系統的網絡的一致性比較差。系統通常要跨越多個網絡區域。同一區域內,網絡資源通常是低售的;而在跨區域的情況下,超售則是常態(超售和低售的鑒別,是通過網卡上可消耗的帶寬和路由器之間的可用帶寬進行比對得出的結論)。智能的負載均衡會盡可能保證通信在同一區域內進行,從而提高性能(降低延遲)并降低總體系統成本(降低區域間的帶寬和光纖需求)。
負載均衡器 vs 代理服務器
業內談到網絡負載均衡器,Load Balancer 以及 Proxy 這兩個術語經常會同樣對待,本文中也把這兩個詞條等價處理(賣弄一下:并非所有的代理都是負載均衡器,但是負載均衡是主流代理的首要功能)。
有人可能會問,有的負載均衡功能是作為客戶端庫的內置功能完成的,這種負載均衡器就不是代理服務器。這一話題本就容易混淆,這一質問更加讓人糊涂。文中會詳述這種負載均衡器的拓撲,這種嵌入的負載均衡方式只是代理的一種特例,應用通過內嵌的庫來完成代理職能,跟典型的負載均衡器的區別僅在于進程內外而已,其整體抽象是一致的。
四層(連接/會話)負載均衡
業界在討論負載均衡技術的時候,經常會分為兩類:L4 和 L7。這一分類來源于 OSI 模型的四層和七層的定義。OSI 模型無法很好的描述負載均衡方案中的復雜性,一個四層負載均衡在完成傳統的四層協議任務例如 UDP 和 TCP 之外,往往還會加入了其他層次的內容。例如一個四層的 TCP 負載均衡還支持 TLS 功能,這算七層負載均衡了么?
2:TCP 終端四層負載均衡
圖 2 展示了一個傳統的四層 TCP 負載均衡器。這個例子中,客戶端向負載均衡器發起了一個 TCP 連接,負載均衡器 終結 了這一連接(也就是說直接響應了 SYN),接下來選擇一個后端,然后創建了到后端的新的 TCP 連接(就是發起了新的 SYN)。圖中的細節不需太過關注,后面的四層負載均衡章節會進行詳細討論。
本節的關鍵點是四層負載均衡一般只在四層的 TCP/UDP 進行操作。籠統的說,負載均衡器負責操作這些字節,保證同一會話的字節們只跟同一個后端打交道。四層負載均衡對通信中的應用細節是一無所知的。通信內容可以是 HTTP、Redis、MongoDB 或者任何應用協議。
七層(應用)負載均衡
四層負載均衡很簡單,目前還在大面積使用。四層負載均衡有什么短處,以至于需要七層(應用)負載均衡呢?例如下面幾個四層的案例:
兩個 gRPC/HTTP2 客戶端要連接到后端,所以通過四層負載均衡器來完成這一過程。
四層負載均衡器為每個接入的 TCP 連接創建一個外發的 TCP 連接,這樣就有了兩個接入、兩個外發的連接。
然而客戶端 A 的請求頻率是每分鐘 1 請求,而客戶端 B 的頻率是每秒鐘 50 請求。
在上述場景中,為客戶端 A 服務的后端,其負載水平僅相當于為客戶端 B 服務的后端的約 1/3000 左右,這明顯違背了負載均衡器的初衷。在所有多工、保持連接的協議中都會發生這樣的情況(多工意思是在單一四層連接中并行發送應用請求;保持連接則意味著在沒有活動請求的情況下,也不會關閉連接)。出于性能方面的考慮(創建連接的成本通常較高,尤其是當使用 TLS 對連接進行加密的情況下),所有的現代協議都包含這兩個特性,所以隨著時間的推移,四層負載均衡的負載不均的情況會越發明顯。七層負載均衡能夠解決這一問題。
圖三:HTTP/2 七層終端負載均衡
圖 3 描述了七層的 HTTP/2 負載均衡。這里客戶端發起了對負載均衡的單個連接。負載均衡器連接到了兩個后端。當客戶端向負載均衡器發送兩個 HTTP/2 流的時候,兩個流會分別送往不同后端。這樣多工客戶端的大量不同的請求會被高效的分發給多個后端。這就是七層負載均衡對現代協議的重要性的來由(因為對應用流量的洞察能力,七層負載均衡還有很多其他好處,后面會詳細描述)。
七層負載均衡和 OSI 模型
之前四層負載均衡章節中說過,用 OSI 模型來描述負載均衡是有困難的。OSI 描述的第七層,涵蓋了負載均衡的多方面功能的臭顯。比如對 HTTP 來說,有以下幾個低級一些的層次:
可選的 TLS。網絡界對 TLS 究竟應該屬于 OSI 模型的哪一層素有爭議。為討論方便,我們放在七層。
物理的 HTTP 協議(HTTP/1或 HTTP/2)。
邏輯 HTTP 協議(Header、Body 和 Trailer)。
消息協議(gRPC、REST 等)。
一個成熟的的七層負載均衡器應該照顧到上面描述的每一層次。另一個七層負載均衡器可能只支持七層分類中的特性的一個子集。總而言之,七層負載均衡器的范疇包含了遠超四層的為數眾多的功能(例子中只提到了了 HTTP;Redis、Kafka、MongoDB 等也都是七層應用協議的例子,也都應受益于七層負載均衡)。
2
負載均衡器特性
下面簡單匯總一下負載均衡器的高層功能。并非所有負載均衡器都提供了所有功能。
服務發現
服務發現就是負載均衡器用于決定可用后臺列表的過程。這一功能的實現方式花樣百出,下面舉一些例子:
靜態配置文件。
DNS。
Zookeeper、Etcd、Consul 等。
Envoy 的 統一數據平面 API。
健康檢查
負載均衡器使用健康檢查功能,來檢測后端是否可用。健康檢查有兩種實現思路:
主動式:負載均衡器周期性的向后端發送 ping (例如一個發送到/healthcheck
端點的 HTTP 請求),以此判斷后端的健康情況。
被動式:負載均衡器通過對主數據流的分析來確定健康情況。比如一個四層負載均衡器,在發現連續三個連接錯誤的情況下,就會判定一個后端不可用;七層負載均衡可能會在連續三個 HTTP 503 響應之后判定這一后端為不健康狀態。
負載均衡
是的,負載均衡器必須為負載做均衡。有了一系列的健康后端,如何選擇后端來響應一個請求或者連接呢?負載均衡算法是一個活躍的研究領域,有 Round Robin 這樣的簡單辦法,也有通過延遲和后端負載情況進行判斷的復雜方案。 Power of 2 least request load balancing 一文,介紹了最流行的兼顧性能和簡易的負載均衡算法之一。
隨機選擇兩個后端,進一步選擇其中負載較低的一個。
Session 粘連
在某些應用中有一個重要需求:同一會話的請求需要到達同一后端。對于緩存、臨時復雜狀態等場景來說這是很必要的。對于“同一會話”的定義有多種形式,可能包括 HTTP Cookie、客戶端連接的屬性以及其他屬性。很多七層負載均衡器具有一些對會話粘連的支持。然而我認為會話粘連是一種天然易碎的情況(處理會話的后端可能會癱瘓),所以對于依賴會話的系統設計應該多加小心。
TLS 終端
TLS 這一話題,不管是邊緣服務還是服務間通訊,都值得大書特書。因此很多七層負載均衡器在 TLS 處理方面都做了大量工作,其中包含終端、證書校驗和綁定,使用 SNI 提供證書等功能。
觀測性
我常說:“觀測性、觀測性、觀測性。”,網絡是一個天生不可靠的東西,負載均衡器應該提供狀態、跟蹤以及日志,協助運維人員甄別故障,從而進行修復。負載均衡器的檢測輸出差距很大。高級的負載均衡器供應包含數字統計、分布式跟中和自定義日志的大量輸出。我認為增強的觀測性并不是從天而降的,負載均衡器需要做出很多附加工作來完成這一任務。對性能造成的負面影響,相對于這一系列數據的好處來說,不值一提。
安全性和拒絕服務***防范
在邊緣部署拓撲(后面會講解)中,負載均衡器經常需要實現各種包含頻率限制、認證以及 DoS 防范(例如 IP 地址的標記和辨識、Tarpitting等方式)等在內的安全功能。
配置和控制平面
負載均衡器應該是可配置的。在大規模部署中,這是一個重要的工作量。通常來說,用來配置負載均衡器的系統被稱為“控制平面”,會有多種實現。拙作 Service Mesh Data Plan vs Control Plan 中對這一部分內容作了更深入的探討。
還有很多
這部分只是對于負載均衡器的功能層面作了一些介紹。下面還會在七層負載均衡器方面做更多的深入討論。
3
負載均衡器的拓撲分類
我們已經對負載均衡器的概念作了一些概括的介紹,四層和七層負載均衡器的區別,以及負載均衡器特性的匯總,接下來我們會針對分布式系統中的負載均衡器部署拓撲進行一些探討(下面的每一種拓撲都是適用于四層和七層負載均衡器的)。
中間代理
4:中間代理負載均衡拓撲
圖 4 描述的這種拓撲對多數讀者來說都是最熟悉的。這一類別包括了 Cisco、Juniper、F5 等硬件產品;云軟件解決方案例如 Amazone 的 ALB 和 NLB 以及 Google 的 Cloud Load Balancer,還有 HAProxy、NGINX 以及 Envoy 這樣的純軟件自主方案。中間代理方案的優勢在于對用戶提供的簡便性。
一般情況下用戶只要通過 DNS 連接到負載均衡器即可,無需擔心其他情況;弱勢在于,負載均衡器存在單點失敗的風險,同時也是可能的性能瓶頸。中間代理通常是一個不便運維的黑盒子。問題出現在哪里?是客戶端還是物理網絡?是中間代理還是后端?很難界定。
邊緣代理
5:邊緣代理負載均衡拓撲
圖 5 實際上是中間代理的一種變體,這種負載均衡器可以通過 Internet 進行訪問。在這一場景下,負載均衡器通常需要提供一些附加的 “API 網關”類功能,例如 TLS 終端、頻率限制、認證以及流量路由等。優勢和劣勢跟中間服代理類似。在一個大的面向 Internet 的分布式系統中,邊緣服務器通常是一個必要的組成部分。
客戶端通常會使用某個不受服務提供商控制的網絡庫,通過 DNS 來訪問這一系統(后面將會討論的嵌入客戶庫或者 Sidecar 代理拓撲都不適合直接運行在客戶端)。另外為了安全方面的考慮,為所有的面向 Internet 的流量使用單一的網關來提供入站流量是一個普遍要求。
嵌入式客戶庫
6:通過嵌入客戶端庫實現負載均衡
為了克服隨中間代理而出現的單點失敗以及性能問題,很多成熟架構把負載均衡直接植入如圖 6 所示的客戶端庫中。不同的庫所支持的功能差別很大,此類產品中最知名的功能豐富的包括 Finagle、Eureka/Ribbon/Hystrix 以及 gRPC(大致基于 Google 的一個稱為 Stubby 的內部系統)。這種方式的好處是把所有負載均衡特性完全分布到每個客戶端,從而避免了前面說到的單點失敗和性能瓶頸。
這種做法的弱勢也很明顯,一個組織使用的所有語言,都需要實現這種客戶端庫。分布式架構下,這種多語言支持的要求會越來越多。這種環境里,每種語言的網絡庫實現造成的成本會讓人望而卻步。最后,在大的服務架構中進行庫升級也是一個很大的挑戰,而在生產環境中并行運行不同的版本,又會給運維造成更大壓力。
結合上面的優劣勢分析,可以知道,在能夠限制編程語言使用,并克服升級痛苦的情況下,這種架構是可以獲得成功的。
Sidecar 代理
7:Sidecar 代理實現負載均衡
嵌入式客戶庫的一個變體就是圖 7 中的 Sidecar 代理拓撲。近年來,這一拓撲以 “Service Mesh” 的概念日益流行。Sidecar 代理背后的思路是,以進程間通信造成的些許延遲為代價,在無需顧慮編程語言鎖定的情況下獲得嵌入客戶端庫的各種優點。目前流行的 Sidecar 負載均衡包括 Envoy、NGINX、HAProxy 以及 Linkerd,我的兩篇文章:Introducing Envoy 和 Service Mesh Data Plan vs Control Plan 對這種結構進行了更細致的描寫。
不同負載均衡器拓撲的總結和優劣勢
中間代理拓撲是最簡單的最典型的方式。他的弱點在于:故障單點、伸縮瓶頸以及黑箱操作。
邊緣代理拓撲和中間代理類似,通常無法忽略。
嵌入客戶端庫的方式提供了最好的性能和伸縮性,不過面向多種語言的開發,和升級所有服務的庫都是很大的挑戰。
Sidecar 代理拓撲比嵌入式客戶端庫要弱,但也避免了這種方式的兩大難點。
總的來說,我認為在服務對服務的情況下,Sidecar 代理拓撲(Service Mesh)會逐漸代替所有其他拓撲形式。為了處理進入 Service Mesh 之前的流量,邊緣代理拓撲會長期存在。
4
四層負載均衡的現狀
四層負載均衡器還有用么?
本文已經談論了很多七層負載均衡器對現代協議的好處,后面還會談到七層負載均衡的功能細節。這是否意味著四層負載均衡器無需存在了?不是的。雖然我認為最終七層負載均衡會完全在服務對服務的場景中取代四層負載均衡器,但四層負載均衡器對邊緣通信還是非常有意義的,這是因為所有現代的大型分布式架構都是用了兩層的四層/七層負載均衡架構來處理互聯網流量。在七層負載均衡器之前部署獨立的四層負載均衡器的好處是:
七層負載均衡器要在應用層面進行更多的精密分析、變換以及路由工作,對于原始流量(每秒數據包或每秒字節數)的負載,其能力要弱于優化過的四層負載均衡器。這一現實使得四層負載均衡器更便于應對拒絕服務***(例如 SYN flood、通用包 flood ***等)。
相對于四層負載均衡器,七層負載均衡器的開發更加活躍,部署更加頻繁,也會有更多 Bug。有了前置的四層負載均衡器,就可以在七層負載均衡器升級期間進行健康檢查和排空,現代四層負載均衡器通常使用 BGP 和 ECMP(后續章節會詳細講解),七層負載均衡的部署通常會較為簡單。最后因為七層負載均衡器相對來說復雜度較高,因此也更容易出現問題,有了前端的四層負載均衡,就可以在出現問題的時候利用路由功能繞過故障節點,提高系統的總體穩定性。
下文中我會講到集中不同設計的中間/邊緣四層負載均衡器。后面提到的設計通常是無法用在客戶庫或 Sidecar 拓撲中的。
TCP/UDP 終端負載均衡器
8:四層終端負載均衡器
還在應用的第一種四層負載均衡器是圖 8中的終端負載均衡器。這和我們介紹四層負載均衡的時候講到的內容是一致的。這種類型的負載均衡器中,使用了兩個的獨立的 TCP 連接:一個用于客戶端和負載均衡器之間;另一個用在負載均衡器和后端之間。
四層終端負載均衡器還有兩個原因:
實現相對簡單。
靠近客戶端的連接終端對性能有顯著影響。尤其是如果客戶使用有損網絡(例如蜂窩網)的話,在進入穩定的有線傳輸到最終目的之前,是容易發生重傳的。換句話說,這種負載均衡器適用于在存在點(Point of Presence )場景下的原始 TCP 連接。
TCP/UDP 透傳負載均衡器
9:透傳負載均衡器
四層負載均衡器的另一種類型就是圖 9所說的透傳負載均衡器。這種類型的負載均衡過程中,TCP連接沒有被負載均衡器終結,每個鏈接的數據包,在經過連接分析和網絡地址轉換(NAT)過程之后,都被轉發給一個選中的后端。首先讓我們定義一下連接跟蹤和 NAT:
連接跟蹤:跟蹤全部活動 TCP 連接的過程。這里包括很多內容,例如握手是否完成,是否收到 FIN,連接發呆了多久,這個連接轉發給哪一個后端等。
NAT:是使用連接跟蹤數據,來更改數據包的 IP/端口信息使之穿過負載均衡器的過程。
有了連接跟蹤和 NAT,負載均衡器就能把客戶端的 TCP 流量幾乎原封不動的的轉發給后端。例如客戶端同1.2.3.4:80
進行通信,選中的后端是10.0.0.2:9000
。客戶端的 TCP 數據包會到達位于1.2.3.4:80
的負載均衡器。負載均衡器會把目標 IP 和端口替換為10.0.0.2:9000
;同時還會把源 IP 替換為負載均衡器的 IP。當后端響應 TCP 連接時,數據包就會返回給負載均衡器,負載均衡器中的鏈接跟蹤和 NAT 再次發揮作用,反向送回數據包。
為什么會使用這一種負載均衡器,而不是前面提到的終端型呢?
性能和資源消耗:透傳型的負載均衡器沒有終結 TCP 連接,無需緩存任何的 TCP 連接窗口。每個連接的狀態存儲非常小,通常使用高效的哈希表查詢即可。正因如此,相對終端負載均衡器來說,透傳型負載均衡器能夠處理更大數量的活動鏈接,單位時間內處理更多的數據包。
允許后端進行擁塞控制:TCP 擁塞控制 是一種機制,讓 Internete 端點對外發數據進行流量控制,防止超量使用帶寬和緩沖。
為直接服務器返回(Direct Server Return = DSR)做基線,以及四層負載均衡集群:透傳負載均衡也是高級四層負載均衡(例如后面將要說到的 DSR 和使用分布式一致性哈希的集群)的基礎。
Direct Server Return (DSR)
10:四層 DSR
圖 10展示的就是 DSR 負載均衡。DSR 構建在前文提到的透傳負載均衡器的基礎之上。DSR 是一種優化方案,只有入站/請求數據包通過負載均衡;出站/響應數據包繞過負載均衡器直接返回給客戶端。使用 DSR 方案的有趣之處在于,很多負載的響應比請求數據量大很多(比如典型的 HTTP 請求和響應)。假設 10% 的流量是請求,另外 90% 是響應,如果使用了 DSR 負載均衡,僅需要 1/10 的容量就能夠滿足系統需要。從前的負載均衡非常昂貴,這一方案能夠顯著降低系統成本并提高可靠性(更少就是更好)。DSR 負載均衡器用下面的方式擴展了透傳負載均衡的概念:
由于響應包不再經過負載均衡器,所以連接跟蹤僅有部分數據,負載均衡器無法知道完整的 TCP 連接狀態。然而還是可以通過對客戶數據包的觀察,對發呆超時的情況來推斷具體狀態。
負載均衡器通常使用 GRE 來封裝 IP 包,并從負載均衡器發送到后端。這樣當后端接收到封裝后的數據包,可以解包并獲得客戶端的端口和地址。這樣后端就能直接跨過負載均衡器直接發送響應包給客戶端了。
DSR 負載均衡器的一個重要部分就是:后端部分的參與了負載均衡過程。后端需要合理的配置 GRE 隧道,并且需要根據網絡的低級細節來配置自己的連接跟蹤以及 NAT 等。
注意不管是 DSR 還是透傳負載均衡器,其中的連接跟蹤、NAT、GRE 等組成部分都有很多不同設計方式。這些設置從負載均衡器到后端都會涉及。這部分內容超出了本文的范圍,就不再深入進行了。
使用高可用配對方式實現容錯
11:使用 HA 對和連接跟蹤實現容錯
到現在,我們要考慮四層負載均衡的容錯設計了。不管是 DSR 還是透傳負載均衡都需要一定數量的鏈接跟蹤和狀態數據存儲在負載均衡器中。負載均衡器宕機了會怎樣?——所有經過這一負載均衡器的連接都會斷掉。可能對應用產生顯著影響。
歷史上,四層負載均衡器是一種從典型供應商(Cisco、Juniper、F5 等)采購的硬件。這些設備非常昂貴,能夠處理大量通信。為了防止單點失敗導致的所有連接中斷,引發應用故障,負載均衡器通常會使用高可用配對的方式進行部署,如圖 11 所示。典型的高可用負載均衡器配置會滿足如下設計:
一對高可用邊緣路由器提供一系列的虛擬 IP(VIP)。這些邊緣路由器使用邊界網關協議(BGP)來發布虛擬 IP。主要邊緣路由器的 BGP 優先級高于備用邊緣路由器,所以正常情況下他會處理所有流量(BGP 是一個超級復雜的協議;為了行文方便,可以理解 BGP 是一種機制,這種機制讓網絡設備可以宣稱自身能夠處理來自其他網絡設備的流量,并且每個連接都會有一個權重,從而影響連接的通信)。
類似的,主要四層負載均衡向 BGP 權重較高的邊緣路由器宣告可用,所以在通常情況下,他會處理所有流量。
兩個邊緣路由器和兩個負載均衡器是交叉連接的,這意味著如果一個邊緣路由器或者一個負載均衡器宕機,或者因為某些原因 BGP 宣布失效,備用設備就會接入,承載所有流量。
上面的設置是目前很多互聯網上的高流量應用還在持續使用的方式,但是這種方案有一些副作用:
VIP 必須通過高可用負載均衡器對流量進行正確的分配。如果單一 VIP 的容量超過了 HA 對,則 VIP 需要分割為多個 VIP。
系統資源使用率很低。通常會有一半的容量在閑置。過去的負載均衡器非常昂貴,所以這一閑置成本也是很高的。
現代分布式系統設計要求比主備模式更好的容錯設計。例如一個系統需要在多個同時出現故障的情況下保持運行。高可用負載均衡對如果遭遇同時故障,就會導致完全癱瘓。
供應商提供的硬件設備價格昂貴,會導致對特定廠商的依賴。使用支持水平擴展的軟件方案對商業硬件設施進行替換,是目前普遍存在的迫切需要。
使用分布式一致性哈希進行容錯和伸縮
12:四層負載均衡器和一致哈希實現容錯和伸縮
前文介紹了通過高可用配對的方式來進行負載均衡器的容錯設置,以及隨之而來的問題。千禧年初,一些大的互聯網基礎設施提供商開始設計和部署新的圖 12 模式的并行四層負載均衡系統。這類系統的目標是:
解決使用成對 HA 模式設計的負載均衡方案帶來的所有問題。
從廠商專屬的專利硬件模式的負載均衡器中遷移出來,使用標準服務器和網卡配合商業軟件方案進行替代。
四層負載均衡器的設計是 fault tolerance and scaling via clustering and distributed consistent hashing 的最佳引用,具體工作模式是:
N 個邊緣路由器在同一 BGP 權重上,聲明所有的 任播 VIP。使用 ECMP(等價多路徑路由) 來保證所有單一 Flow 能夠到達同一個邊緣路由器。一個 Flow 通常是一個由源 IP/端口和目的 IP/端口 構成的元組。(簡單說,ECMP 是一個在使用一致性哈希連接的獨立加權網絡上分發數據包的方式)。邊緣路由器并不在意哪些數據包去了哪里。一般會傾向于把來自于一個 Flow 所有數據包發送給同一套連接,以此避免亂序包導致的性能損失。
N 個四層負載均衡器向邊緣路由器在同一個 BGP 權重上聲明所有的 VIP。再次借助 ECMP,邊緣路由器會選擇為同一個 Flow 選擇同一個負載均衡器。
每個四層負載均衡器會進行部分的連接跟蹤,為這一 Flow 使用一致性哈希選擇一個后端。從負載均衡器到后端的數據包會使用 GRE 進行封裝。
接下來使用 DSR 將相應包直接從后端通過邊緣路由器發送會客戶端。
四層負載均衡器使用的一致性哈希算法是一個活躍的研究領域,其中涉及合理分配、減小延遲、后端變更成本以及最小化內存開支等各方面要素。這方面的完整討論也超出了本文范圍。
接下來看看這種設計如何克服 HA 配對方式的缺點:
新的邊緣路由器和負載均衡器可以按需加入。一致性哈希會在各個層次上使用,在加入新機器的時候,盡可能降低受影響的 Flow 數量。
在保持對突發消耗的支持能力以及容錯能力的同時,可以提高資源的使用率。
邊緣路由器和負載均衡都可以使用使用普通硬件,僅是傳統硬件負載均衡成本的幾分之一(下文會進一步說明)。
行文至此,有讀者可能會問:“為什么不讓邊緣路由器直接通過 ECMP 和后端進行通信?為什么我們還需要負載均衡器?”。答案是 DoS 防范以及后端運維難度。如果沒有負載均衡器支持,每個后端都需要加入 BGP,而且難于進行滾動更新。
所有的現代四層負載均衡系統都在向著這一方案(或其變體)遷移。兩個最為公眾所知的例子就是 Google 的 Maglev 以及 Amazon 的 Network Load Balancer (NLB)。目前還沒有任何開源負載均衡器實現了這一設計,然而據我所知,有公司要在 2018 年發布一個這樣的產品。我很期待他的出現,這一產品將會填補開源網絡組件的重要空白。
當前七層負載均衡的技術狀態
Current state of the art in L7 load balancing The proxy wars in tech currently is quite literally the proxy wars. Or the "war of the proxies". Nginx plus, HAProxy, linkerd, Envoy all quite literally killing it. And proxy-as-a-service/routing-as-a-service SaaS vendors raising the bar as well. Very interesting times!
是的,的確是這樣。近幾年我們看到七層負載均衡/代理技術的開發工作開始復興。隨著分布式微服務系統的不斷推進,這方面也會不斷進步。從基礎上看,目前對于靠不住的網絡的依賴越發嚴重,帶來更高的運維難度。從長遠看,自動伸縮、容器編排等技術的大量使用,意味著靜態 IP、靜態文件的時代已經過去了。系統不僅更多的使用網絡,而且更加動態,需要新的負載均衡功能。在本節中我們簡單歸納一下現在七層負載均衡器的功能。
協議支持
現代七層負載均衡器加入了很多不同協議的顯式支持。負載均衡器對應用通訊認識越多,就越能做好監控輸出、高級負載均衡和路由等功能。例如目前 Envoy 顯式的支持七層協議解析和路由的范圍包括 HTTP/1、HTTP/2、gRPC、Redis、MongoDB 以及 DynamoDB。包括 MySQL 和 Kafka 在內的更多協議會逐漸添加進來。
動態配置
如上文所述,分布式系統的大行其道,需要有動態配置能力來提高系統的動態和控制能力。Istio就是一個這種系統的例子。請參考 Service Mesh Data Plan vs Control Plan 來獲取更多這方面的內容。
高級負載均衡
七層負載均衡器一般都有內置的高級負載均衡支持,例如超時、重試、頻率控制、斷路器、Shadow、緩沖、基于內容的路由等。
可觀測性
上文中也提到過,負載均衡的一個常見功能,越來越多的動態系統被部署,調試難度也水漲船高。健壯的協議規范觀測輸出可能是未來七層負載均衡器要提供的最重要功能之一。統計數字、分布式跟蹤以及可以定義日志的輸出,目前已經成為對器層負載均衡解決方案的必須要求。
擴展性
現代七層負載均衡器需要能夠簡單的加入定制功能。這一功能可以通過編寫可插接過濾器,并載入到負載均衡器的方式來實現。很多負載均衡器還支持腳本擴展,例如 Lua。
容錯
在講四層負載均衡的容錯時頗費了一番口舌。七層負載均衡的容錯又怎樣呢?一般來說我們認為七層負載均衡器(的工作負載)是無狀態的可拋棄的。使用普通軟件就能夠簡單的對七層負載均衡器進行水平擴展。另外七層負載均衡的流量處理和狀態跟蹤的復雜度要遠超四層。設置七層負載均衡器的 HA 配對在技術上是可行的,但會非常繁雜。
總的說來,不管是四層還是七層的負載均衡,業界都在嘗試走出 HA 配對模式,轉向一致性哈希為基礎的水平擴展方式。
更多
七層負載均衡器正在高速發展。可以參考 Envoy 架構概覽。
5
全局負載均衡和中心控制平面
13:全局負載均衡
未來會有越來越多的獨立負載均衡器以商品設備的面目呈現。我認為真正的創新和商業機會來自于控制平面。圖 13展示了一個全局負載均衡系統。在本例中有一些不同的東西:
每個 Sidecar 代理和三個不同區域的后端進行通信。
如圖,90% 的流量會被發送到 C 區,A B 兩區分別得到 5%。
Sidecar 代理和后端都會周期性的向全局負載均衡器進行匯報。這樣全局負載均衡器就可以根據延遲、成本、負載、失敗率等數據進行精密決策。
全局負載均衡周期性的使用當前的路由信息配置每個 Sidecar 代理。
全局負載均衡能做一些單一負載均衡器做不到的事情,例如:
對分區故障的自動檢測和路由繞行。
應用全局的安全和路由策略。
使用機器學習和神經網絡,對異常流量進行檢測和防范,包括分布式拒絕服務***。
提供中央界面和可視化支持,讓工程師能夠以聚合的角度,對整個分布式系統進行監控和運維。
全局負載均衡器要成為現實,他的數據平面必須具有強大的動態配置能力。請參考我的博客:Envoy's universal data plane API,以及 Service Mesh Data Plan vs Control Plan 。
6
結論,以及負載均衡器的未來
綜上所述,本文的主旨:
負載均衡器是現代分布式系統的關鍵組件。
有兩種負載均衡器:四層和七層。
四層和七層負載均衡器都與現代架構相關。
四層負載均衡器正在朝著基于一致性哈希的水平擴展方案的方向進行遷移。
由于動態微服務架構的成長,七層負載均衡器得以快速發展。
控制平面和數據平面的拆分,和全局負載均衡,是負載均衡的未來發展方向和機會來源。
業界正激進的邁向標準硬件和軟件的開源解決方案。我相信傳統的像 F5 這樣的負載均衡廠商會被開源軟件和云供應商取代。傳統的路由器、交換機廠商,例如 Arista/Cumulus 等,短期內會有更好的發展,但最終也會被共有云提供商及其自研物理網絡所取代。
總的說來,我認為這是計算器網絡的奇跡年代。多數系統開始向開源和軟件方向轉變,極大的提高了迭代速度。未來,分布式系統又向無服務器計算進軍,底層網絡和負載均衡系統的復雜性也勢必齊頭并進,水漲船高。
看了以上關于負載均衡那點事兒的一些淺見,如果大家還有什么地方需要了解的可以在億速云行業資訊里查找自己感興趣的或者找我們的專業技術工程師解答的,億速云技術工程師在行業內擁有十幾年的經驗了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。