[翻譯] 介紹現代網路負載平衡與代理伺服器

原文(Source): https://blog.envoyproxy.io/introduction-to-modern-network-load-balancing-and-proxying-a57f6ff80236

什麼是網路負載平衡 (network load balancing) 與 代理伺服器的代理行為 (proxying)?
維基百科是這樣定義負載平衡的

> 負載平衡藉由工作量分配到多台運算資源, 例如: 主機, 主機叢集, 網路連結, CPU,  硬碟等.
> 負載平衡盡量最佳化資源的使用, 最大化每個最大化每個資源的吞吐量(生產能力), 最小化反應時間, 避免單一資源工作量過重
> 使用多個資源來當負載平衡來提升可靠與高可用而不是單一個資源
> 負載平衡總是使用獨立的軟體或硬體, 例如獨立的 multilayer switch, 或是 DNS主機的程式

上面的定義用於各資訊領域的各方面, 不單單只有網路而已.
作業系統使用負載平衡在實體處理器去分配運算任務, 容器編排服務像是K8S使用負載平衡在不同的主機叢集中去分配任務, 而網路負載平衡器則是將網路上進來的任務分配給可用的後端主機們. 剩下的文章主要都是講解關於網路負載平衡.

圖1
圖1展示了從應用層來看網路負載平衡. 許多的用戶端(Client)透過只需要向 load balancer 請求, load balancer就會將這些request, 也就是上述提到的任務分配給可用的後端服務.

Load balancer位於Client 與後端之間執行幾個重要的任務:

  • 服務發現 (Service discovery)
    • 後端的服務在系統的哪裡, 他們的IP(位置)是什麼? (也就是load balancer該如何與後端主機溝通)
  • 服務的狀態檢查 (Health checking)
    • 現在的服務是否是可接受請求的
  • 負載平衡 (Load Balancing)
    • 該用什麼樣的演算法去平均將request分配給可用的服務

在分散式系統使用負載平衡主要有幾個好處:

  • 主機抽象 (Naming abstraction):
    • 每個client 不需要知道每個後端服務在哪, 只需要利用預先定義好的機制向負載平衡器發出請求, 這些機制包含內建的函式庫與大家都知道的DNS/IP/port
  • 容錯 (Fault tolerance):
    • 負載平衡器透過服務的狀態檢查與不同的演算法, 可以有效率地避開狀態不好的後端服務, 這代表後端工程師可以是以緊急的狀態或是悠閒(leisure)的狀態修復狀態不好的後端服務
  • 成本與效能 (Cost and performance benefits):
    • 分散式系統的網路很少是在同一區的, 分散式系統更偏向將系統分佈在不同的網路區域(network zones)中, 如果都在同個區, 網路線路的頻寬很容易會滿. 如果是跨區, 超額使用(oversubscription)的情況就會變成被分配到各區(在這個情境 over/undersubscription是指頻寬可消耗的總額是路由器可用的頻寬的多少百分比). 聰明的負載平衡技術可以使得request的流量盡可能地保持跨區, 這樣會提高效能(降低延遲), 減少整體系統負擔(較低的頻寬與光纖的需求)

負載平衡 vs 代理


當提到網路負載平衡時, load balancer 與 proxy通常在這個產業裡, 是可粗略地交換使用.
這篇文章也會將這兩個詞是為相同的意思 (正常來說, 不是所有代理伺服器都是負載平衡器, 但大部分的代理伺服器都將負載平衡的工作視為一個主要功能)

關於負載平衡會有一些小爭論, 是在於負載平衡的技術已經有些會鑲嵌在客戶端的函式庫中, 但負載平衡器並不是真的代理伺服器. 負載平衡器的topologies的細節會稍後討論. 本文會將鑲嵌在客戶端中的負載平衡技術, 當作是特例的代理伺服器.

L7 載平衡 (應用層)


L4 負載平衡是簡單而且可以看到仍被廣泛使用. 但但有什麼缺點是L4負載平衡比不上L7的呢?
看一下下面幾個L4特例:

  • 兩個gRPC/HTTP2用戶端想要與後端溝通, 所以他們透過L4負載平衡器
  • L4負載平衡器對每一個用戶端的請求都會產生一個對外的TCP連線, 所以兩個用戶端就是兩個連線
  • 然而, 用戶A送出一個請求, 但持續連接1分鐘, 用戶B則是1秒送出50個請求
在上面的情境之下, 後端處理用戶A的的負擔會是大約會是處理用戶B的3000倍左右!
這是個很嚴重的問題, 而且失去了使用負載平衡器的目的. 這個問題在 multiplexing, kept-alive 協定也會發生. (Multiplexing是指同時送出多個應用程式的請求在單一L4連接上, kept-alive則是當沒有其他請求時, 也不中斷連線)
現在的協定為了效能的因素大多都演變成multiplexing與kept-alive. (通常來說, 建立連線, 特別是TLS的連線所消耗的資源都比較大), 所以L4負載平衡器的通訊資料不匹配會隨著時間越來越明顯. 這個問題在L7負載平衡器已被修正.
圖3: HTTP/2 L7處理載平衡的過程

圖3顯示了L7 HTTP2/2 負載平衡器. 在這張圖, 用戶端與負載平衡器建立一個HTTP/2 TCP連線. 接著負載平衡器產生兩個後端的連線. 當用戶端送出兩個HTTP/2 串流給負載平衡器時, 串流1會送給後端伺服器1, 串流2則是送給後端伺服器2. 此外, 即使用戶使用了multiplexing送出大量不同的請求, 也會被有效率地分配給後端. 這就是爲什麼L7負載平衡對於現代的協定來說是如此重要的. (L7負載平衡由於其可以檢視應用層流量的能力會產生許多好處, 下面會再提到)


L7載平衡與OSI模型

就像上面在L4負載平衡中提到的, L4無法此用OSI模型去描述. L7可以的原因是因為他本身就是基於OSI模型去描述的, 而且本身包含了許多分散的負載平衡服務抽象層. ex: 對於HTTP流量的可以看看下面的子服務層

  • Optional Transport Layer Security (TLS).有人會爭論關於OSI模型與TLS屬於哪. 為此本文只討論TLS L7.
  • 實體的 HTTP 協定(HTTP/1 或 HTTP/2)
  • 邏輯的 HTTP 協定(headers, body資料, 還有trailers)
  • 訊息協定 (ex: gRPC, REST等等)

一個成熟的L7負載平衡器會提供類似上面提到的特色功能. 另外L7負載平衡器會只有一個小的子集合放在L7分類特色功能.總而言之, L7負載平衡器比起L4來說, 涵蓋許多複雜的功能. (當然這段只提到HTTP; Redis, Kafka, MongoDB等也都是受益於L7負載平衡器的L7應用層協定的例子)

載平衡的特色


在這段, 本文會簡短地總結負載平衡器提供的高階特色. 但不是所有的負載平衡器都會有提供這些特色

服務發現 (Service discovery)

服務發現是由負載平衡決定哪些是可用的後端服務. 方法有很多種, 以下是幾個例子


服務可用檢查(Health checking)

Health checking是負載平衡會去檢查後端服務是否能夠去處理流量. 通常有兩種分類

  • 主動
    • 負載平衡藉由定時固定的時間區間主動去ping後端去評估(gauge)是否為健康的
    • 通常是透過送出http請求給 /healthcheck 的api端點
  • 被動
    • 負載平衡藉由資料流來確定服務的健康狀態, ex: L4負載平衡器可能會透過得到連續三個連線錯誤來決定目前後端服務是有問題的. L7負載平衡器則是透過得到連續的三個HTTP 503回應來認為服務是不健康的

負載平衡(Load balancing)

負載平衡器必須要有負載平衡的功能, 如何在一堆健康的後端服務中去選擇要將請求導過去?
負載平衡演算法從最簡單的隨機分配與輪流分配到更複雜的演算法, 會將延遲時間也納入考量. 最廣為使用的是將效能最廣為使用的是將效能與簡單性. 也就是 power of 2 least request load balancing.

Sticky Sessions


在某些服務中, 每次連線的session要維持在同台後端服務是很重要的. 為達到這個目的, 可能會需要使用快取或是或是暫時性的複雜的解法. Session 的定義很多, 有可能包含HTTP cookies, 用戶端連線的屬性, 或著是其他屬性. 許多L7負載平衡器有支援一些sticky session.
但 sticky session天生就有缺陷, 所以最好系統是盡量少使用到 sticky session.

TLS termination


TLS提供服務對服務間的安全通訊是可以再多一篇文章來介紹. 很多 L7 負載平衡器處理很大量的TLS加密包含termination, 憑證識別與驗證 , 憑證服務使用 SNI

Observability


"Observability, observability, observability" 很重要所以說三次. 網際網路天生就是不可靠的. 負載平衡器經常負責匯出服務狀態, 追蹤服務並且作log幫助操作者找出服務哪裡出錯, 並修復它. 負載平衡器的observability輸出很多樣化. 更多進階的負載平衡器提供大量的輸出包含: 數據相關的資料, 分散式追蹤, 客製化的log

安全與阻斷式攻擊緩和(Security and DoS mitigation)

特別是在最末端的部署拓樸, 負載平衡器通常會實作許多的安全特色,  例如: 限速, 身份驗證,
阻斷式攻擊緩和(例如: IP address tagging and identification, tarpitting, etc.)

Configuration and control plane


負載平衡器需要被設定. 在大型部署中, 這是一個很重要的工作. 通常來說, control plane是設定負載平衡器的系統, 而且實作方式很廣. 更多資訊可以看 post on service mesh data plane vs. control plane.

負載平衡器的拓墣種類(Types of load balancer topologies)

剛剛已經從高階角度來看負載平衡器在L4與L7的差異, 並總結各自的特色功能, 接下來會換成負載平衡器如何在分散式系統中被部署的架構. 接下來說的都適用於L4, L7負載平衡器

Middle proxy

圖4:  middle proxy載平衡的拓墣

圖4是The middle proxy 拓墣是大多數讀者最可能得到的負載平衡. This category 包含來自Cisco, Juniper, F5等硬體; 雲端解決方案像是AWS的 ALB and NLB 與 Google的 Cloud Load Balancer; and 自己處理的純軟體解法像是 HAProxy, NGINX, 與 Envoy. middle proxy的好處就是對使用者來說很簡單. 一般來說,使用者透過DNS連到負載平衡器, 而不需要擔心其他的東西. middle proxy的缺點是單點失效的問題, 也就是scale的瓶頸. middle proxy也同時是個黑盒, 使得維運困難. 這是用戶端的問題? 在實體網路? 在 middle proxy? 在後端? 這很難去分辨.

Edge proxy


圖5: Edge proxy載平衡的拓墣
圖5是edge proxy拓墣, 跟middle proxy拓墣有差異, 差異在於負載平衡器是透過網路網路上取得的. 在這個情境下, 負載平衡提供額外的API Gateway功能像是TLS termination, rate limiting, 驗證, 與成熟的流量路由. edge proxy的優點與middle proxyㄧ樣. 一個警告是在大型的internet-facing分散式系統中部署一個獨立的edge proxy通常是無可避免的. 用戶通常需要透過DNS使用任意的服務提供者不需要控制內嵌的用戶端函式庫的網路函式庫 (or sidecar proxy topologies在稍後會提到). 此外, 因為安全性, 有一個單一gateway是對於所有internet-facing的系統入口是有利的.

Embedded client library

圖6:載平衡透過內嵌的用戶端函式庫
為了避免middle proxy topologies中單點失效與scale議題 , 更成熟的架構需要靠內嵌負載平衡器透過函式庫到服務中, 如圖6所示. 函式庫有非常大的變化在支援的特色功能上,但他們當中有些有豐富特色的像是Finagle, Eureka/Ribbon/Hystrix, 與 gRPC.主要的優點是他很好地分散了用戶到負載平衡器, 此外也沒有單點失效與scale的議題. 主要的缺點是用戶端函示庫必須實作每個程式語言. 分散式架構變得非常多程式語言的. 在這個環境下, 重新實作的成本、是一個非常成熟的網路函式庫是高到令人望之卻步的. 最後, 部署 library 升級跨大型服務架構可以是非常痛苦的.
上述提到的函式庫對於已經可以限制程式語言擴散與克服函式庫升級的公司們來說是成功可用的

Sidecar proxy

圖7: 透過 sidecar proxy 載平衡
在圖7, sidecar proxy 拓墣是不同的內嵌用戶端函式庫 load balancer 拓墣. 近幾年來, 這個拓墣被通稱為 service mesh. sidecar proxy背後的想法是以輕微的延遲成本為代價,藉由跳到一個不同的process上,所有的內嵌函式庫都可以不用被程式語言lock-in.最受歡迎的 sidecar proxy load balancers 是 Envoy, NGINX, HAProxy, and Linkerd. 更詳細的請見 blog post introducing Envoy 以及 post on the service mesh data plane vs. control plane.

總結不同的負載平衡器拓墣好處與壞處

  • middle proxy topology是去消耗連線典型最簡單的負載平衡拓墣. 缺點是有單點失效, scaling 限制, 與黑箱操作不易偵測問題.
  • edge proxy topology跟middle proxy很像, 但無法避免
  • The embedded client library 拓墣提供最好的效能與彈性,但需要去實作每個程式語言以及處理所有服務中客戶端函式庫的升級 
  • The sidecar proxy 拓墣效能沒有embedded client library這麼好, 但是沒有 embedded client library 的限制


L4放置在L7之前的優點:
  • 因為L7處理的大多是更成熟的分析, 應用程式的路由, 資料的轉換, 甚至比優化過的L4更能處理小部分的原始資料, 但 L4比較好的位置應該是處理DDoS攻擊
  • L7負載平衡器往往更積極地開發,部署更頻繁,因此比L4負載平衡器有更多的bug。在L7負載平衡器部署期間,有一個L4負載平衡器可以在L7負載平衡器部署期間進行健康檢查和排空,這比現代L4負載平衡器(通常使用BGPECMP)(以下將詳細介紹)的部署機制要容易得多。最後,因為L7負載平衡器更可能由於其功能的複雜性而出現錯誤,所以擁有一個可以繞過故障和異常路由的L4負載平衡器會導致整個系統更穩定

TCP/UDP終端負載平衡器

圖8: L4 終端載平衡器

第一種類型的L4負載平衡器仍在使用,如圖8所示的終端負載平衡器。這與我們在上面介紹的L4負載平衡中看到的負載平衡器相同。在這種類型的負載平衡器中,使用兩個離散的TCP連接:一個在客戶端和負載平衡器之間,另一個在負載平衡器和後端之間。

L4終端負載平衡器仍然有兩個可以使用的原因:
  • 他們相對容易實施。
  • 靠近客戶端的連接終端對客戶端有很大的影響(低延遲)。具體來說,如果終端負載平衡器可以放置在使用有損網絡(例如蜂窩)的客戶端附近,那麼在將數據轉移到可靠的光纖傳輸途中直至其最終位置之前,重傳可能會更快地發生。換句話說,這種類型的負載平衡器可能用於原始TCP連接終止的存在點(POP)場景。

TCP/UDP passthrough load balancers

圖9: L4 passthrough load balancer
第二種類型的L4負載平衡器是圖9所示的直通負載平衡器。在這種類型的負載平衡器中,TCP連接並未由負載平衡器終止。相反,在連接跟踪和網絡地址轉換(NAT)發生後,將每個連接的數據包轉發到選定的後端。首先,我們來定義連線追蹤和NAT:
  • 連線追蹤:跟踪所有活動TCP連接狀態的過程。這包括數據,例如握手是否完成,是否收到FIN,連接空閒多久,為連接選擇了哪個後端,等等。 
  • NAT:NAT是使用連線追蹤數據在穿越負載平衡器時更改數據包的IP /端口信息的過程。
使用連線追蹤和NAT,負載平衡器可以將大部分原始TCP流量從客戶端傳遞到後端。例如,假設客戶端正在與1.2.3.4:80交談,並且所選後端位於10.0.0.2:9000。客戶端TCP數據包將在1.2.3.4:80到達負載平衡器。然後,負載平衡器將使用10.0.0.2:9000交換數據包的目標IP和端口。它還會將數據包的源IP與負載平衡器的IP地址進行交換。因此,當後端在TCP連接上響應時,數據包將返回到負載平衡器,在那裡進行連接跟踪並且NAT可以在相反的方向再次發生。

為什麼會使用這種類型的更複雜的負載平衡器來代替上一節中描述的終端負載平衡器?有幾個原因:
  • 效能和資源使用情況:由於直通負載平衡器不是終止TCP連接,所以不需要緩衝任何TCP連接窗口。每個連接存儲的狀態量非常小,通常通過高效的散列表查找來訪問。因此,直通負載平衡器通常可以處理比終端負載平衡器大得多的使用中的連接數和每秒封包數(PPS)。 
  • 允許後端執行自定義擁塞控制:TCP擁塞控制是因特網上的端點節制發送數據以避免壓倒可用帶寬和緩衝區的機制。由於直通負載平衡器不會終止TCP連接,因此它不參與擁塞控制。這個事實允許後端根據他們的應用使用情況使用不同的擁塞控制算法。它還可以更容易地進行擁塞控制更改的實驗(例如,最近的BBR部署)。 形成直接服務器返回(DSR)和群集L4
  • 負載平衡的基準:對於更高級的L4負載平衡技術(如DSR和具有分佈式一致性散列的群集(以下各節中討論)),需要直通負載平衡。

Direct server return (DSR)

圖10: L4 Direct server return (DSR)
直接服務器返回(DSR)負載平衡器如圖10所示. DSR基於前一節中介紹的直通負載平衡器構建。 DSR是一種優化,只有入口/請求數據包才能通過負載平衡器。出口/響應數據包在負載平衡器周圍直接返回到客戶端。執行DSR很有趣的主要原因是,在許多工作負載中,響應流量大於請求流量(例如,典型的HTTP請求/響應模式)。假設10%的流量是請求流量,90%的流量是響應流量,如果使用DSR,則具有1/10容量的負載平衡器可以滿足系統需求。由於歷史上的負載平衡器非常昂貴,因此這種優化可能會對系統成本和可靠性產生實質性影響(總是更好)。 DSR負載平衡器將直通負載平衡器的概念擴展如下:
  • 負載平衡器通常仍然執行部分連接跟踪。由於響應數據包不會遍歷負載平衡器,所以負載平衡器不會意識到完整的TCP連接狀態。但是,負載平衡器可以通過查看客戶端數據包並使用各種類型的空閒超時來強烈推斷狀態。
  • 負載平衡器通常使用通用路由封裝(GRE)來封裝從負載平衡器發送到後端的IP數據包,而不使用NAT。因此,當後端接收到封裝的數據包時,它可以對其進行解封裝並知道客戶端的原始IP地址和TCP端口。這允許後端直接將資料回給客戶端,而不通過負載平衡器回傳數據包。
  • DSR負載平衡器是後端參與負載平衡的一個重要的部分。後端需要有一個正確配置的GRE隧道,並且根據網路設置的低層詳細信息,可能需要自己的連接追蹤,NAT等。
請注意,在直通負載平衡器和DSR負載平衡器設計中,可以通過負載平衡器和後端設置連接跟踪,NAT,GRE等多種方式。不幸的是,這個主題超出了本文的範圍。

Fault tolerance via high availability pairs

圖11:通過HA對和連接跟踪的L4容錯
到目前為止,我們一直在考慮單獨設計L4負載平衡器。直通和DSR負載平衡器都需要負載平衡器本身的一定數量的連接追蹤和狀態。如果負載平衡器掛了怎麼辦?如果負載平衡器的單個實例死亡,則所有通過負載平衡器的連接都將被切斷。取決於應用程序,這可能會對應用程序性能產生重大影響。

從歷史上看,L4負載平衡器是從典型供應商(Cisco,Juniper,F5等)購買的硬件設備。這些設備非常昂貴並且處理大量的流量。為了避免單個負載平衡器故障切斷所有連接並導致大量應用程序中斷,負載平衡器通常部署在高可用性對中,如圖11所示。典型的HA負載平衡器設置具有以下設計:

  • 一對HA邊緣路由器為一些虛擬IP(VIP)提供服務。這些邊緣路由器使用邊界網關協議(BGP)宣布VIP。主邊緣路由器具有比備份更高的BGP權重,因此在穩定狀態下,它將為所有流量提供服務。 (BGP是一個非常複雜的協議;就本文而言,僅考慮BGP是網絡設備宣布它們可用於從其他網絡設備獲取流量並且每個鏈路都可以具有優先考慮鏈路流量的權重的機制)的機制。
  • 同樣,主L4負載平衡器向邊緣路由器宣布自己的BGP權重高於備份,因此在穩定狀態下它將服務於所有流量。
  • 主負載平衡器交叉連接到備份,並共享其所有連接跟踪狀態。因此,如果主要死亡,備份可以接管處理所有活動連接。
  • 兩台邊緣路由器和兩台負載平衡器都是交叉連接的。這意味著如果其中一個邊緣路由器或其中一個負載平衡器死亡,或者由於某種其他原因而撤消BGP通知,備份可以接管所有通信。
上述設置是今天仍然有多少高流量的互聯網應用。但是,上述方法存在重大缺陷:
  • 考慮到容量使用情況,跨負載平衡器對正確分片。如果單個VIP增長超過單個HA對的容量,則VIP需要分成多個VIP。
  • 系統的資源使用情況很差。 50%的容量在穩定狀態下閒置。鑑於歷史上硬體負載平衡器非常昂貴,這導致大量閒置資本。
  • 現代分佈式系統設計比主動/備份提供更高的容錯能力。例如,最佳地,系統應該能夠承受多個同時發生的故障並繼續運行。如果活動負載平衡器和備份負載平衡器同時死亡,則HA負載平衡器對可能完全失敗。
  • 來自供應商的專有大型硬件設備非常昂貴並導致供應商鎖定。通常需要用這些水平可擴展的軟體解決方案替換這些硬體設備,這些解決方案使用商用計算服務器構建。

Fault tolerance and scaling via clusters with distributed consistent hashing

圖12: L4 fault tolerance and scaling via clustered load balancers and consistent hashing
上一節介紹了通過HA對的L4負載平衡器容錯以及該設計中固有的問題。從21世紀初到中期,大型互聯網基礎設施開始設計和部署新的大規模並行L4負載平衡系統,如圖12所示。這些系統的目標是:
  • 緩解前一節中描述的HA對設計的所有缺點。
  • 從供應商的專有硬體負載平衡器轉移到使用標準計算服務器和NIC構建的商品軟體解決方案。
這種L4負載平衡器容錯設計,透過集群和分佈式一致性散列進行擴展。它的工作原理如下:

  • N個邊緣路由器宣稱所有Anycast VIP是相同的BGP權重。等價多路徑路由(ECMP)用於確保通常來自單個流的所有數據包到達同一邊緣路由器。流程通常是來源IP /端口和目標IP /端口的4元組。 (簡而言之,ECMP是通過使用一致散列來在一組相同加權的網絡鏈路上分發數據包的一種方式)。儘管邊緣路由器本身並不特別關心哪些分組到達哪裡,但通常優先的是,來自流的所有分組都經過相同的一組鏈路,以避免亂序分組降低性能。
  • N個L4負載平衡器機器宣稱所有VIP以與邊緣路由器相同的BGP權重。再次使用ECMP,邊緣路由器通常會為流選擇相同的負載平衡器機器。
  • 每個L4負載平衡器機器通常會執行部分連接追蹤,然後使用一致性hash來為資料流選擇該去哪個後端。 GRE用於封裝從負載平衡器發送到後端的數據包。
  • 然後使用DSR通過邊緣路由器將數據包從後端直接發送到客戶端。
  • L4負載平衡器使用的實際一致hash算法是一個積極研究的領域。主要圍繞平衡負載進行權衡,盡量減少延遲,盡量減少後端更改期間的中斷,
  • 並儘量減少內存開銷。有關此主題的完整討論超出了本文的範圍。

Fault tolerance via high availability pairs

圖11:通過HA對和連接跟踪的L4容錯
到目前為止,我們一直在考慮單獨設計L4負載平衡器。直通和DSR負載平衡器都需要負載平衡器本身的一定數量的連接追蹤和狀態。如果負載平衡器掛了怎麼辦?如果負載平衡器的單個實例死亡,則所有通過負載平衡器的連接都將被切斷。取決於應用程序,這可能會對應用程序性能產生重大影響。


從歷史上看,L4負載平衡器是從典型供應商(Cisco,Juniper,F5等)購買的硬體設備。這些設備非常昂貴並且處理大量的流量。為了避免單個負載平衡器故障切斷所有連接並導致大量應用程序中斷,負載平衡器通常部署在高可用性對中,如圖11所示。典型的HA負載平衡器設置具有以下設計:
  • 一對HA邊緣路由器為一些虛擬IP(VIP)提供服務。這些邊緣路由器使用邊界網關協議(BGP)宣告VIP。主邊緣路由器具有比備份更高的BGP權重,因此在穩定狀態下,它將為所有流量提供服務。 (BGP是一個非常複雜的協議;就本文而言,僅考慮BGP是網絡設備宣布它們可用於從其他網絡設備獲取流量並且每個鏈路都可以具有優先考慮鏈路流量的權重的機制)的機制。
  • 同樣,主L4負載平衡器向邊緣路由器宣布自己的BGP權重高於備份,因此在穩定狀態下它將服務於所有流量。
  • 主負載平衡器交叉連接到備份,並共享其所有連接追蹤狀態。因此,如果主要的那台掛了,備份可以接管處理所有使用中的連接。
  • 兩台邊緣路由器和兩台負載平衡器都是交叉連接的。這意味著如果其中一個邊緣路由器或其中一個負載平衡器死亡,或者由於某種其他原因而撤消BGP通知,備份可以接管所有通信。
上述設置是今天仍然有多少高流量的互聯網應用。但是,上述方法存在很大的不足:
  • 考慮到容量使用情況,VIP必須在HA負載平衡器對之間進行正確分片。如果單個VIP增長超過單個HA對的容量,則VIP需要分成多個VIP。
  • 系統的資源使用情況很差。 50%的容量在穩定狀態下閒置。鑑於歷史上硬體負載平衡器非常昂貴,這導致大量閒置資本。
  • 現代分佈式系統設計比主動/備份提供更高的容錯能力。例如,最佳地,系統應該能夠承受多個同時發生的故障並繼續運行。如果活動備份負載平衡器和備份負載平衡器同時死亡,則HA負載平衡器對可能完全失敗。
  • 來自供應商的專有大型硬件設備非常昂貴並導致供應商鎖定。通常需要用這些水平可擴展的軟件解決方案替換這些硬件設備,這些解決方案使用商用計算服務器構建。

透過水平擴展叢集與容錯, 使用一致的hashing(Fault tolerance and scaling via clusters with distributed consistent hashing)

圖12:L4容錯和通過集群負載平衡器和一致性hash的擴展

上一節介紹了通過HA對的L4負載平衡器容錯以及該設計中固有的問題。從21世紀初到中期,大型互聯網基礎設施開始設計和部署新的大規模並行L4負載平衡系統,如圖12所示。這些系統的目標是:
  • 緩解前一節中描述的HA對設計的所有缺點。
  • 從供應商的專有硬體負載平衡器轉移到使用標準計算服務器和NIC構建的商品軟體解決方案。
這種L4負載平衡器設計最好稱為容錯,透過集群和分佈式一致性hash進行擴展。它的工作原理如下:
  • N個邊緣路由器以相同的BGP權重宣告所有Anycast VIP。等價多路徑路由(ECMP)用於確保通常來自單個流的所有數據包到達同一邊緣路由器。流程通常是來源IP /端口和目標IP /端口的4元組。 (簡而言之,ECMP是通過使用一致散列來在一組相同加權的網絡鏈路上分發數據包的一種方式)。儘管邊緣路由器本身並不特別關心哪些分組到達哪裡,但通常優選的是,來自流的所有分組都經過相同的一組鏈路,以避免亂序分組降低性能。
  • N個L4負載平衡器機器以與邊緣路由器相同的BGP權重宣布所有VIP。再次使用ECMP,邊緣路由器通常會為流選擇相同的負載平衡器機器。
  • 每個L4負載平衡器機器通常會執行部分連接跟踪,然後使用一致性hash來為資料流選擇後端。 GRE用於封裝從負載平衡器發送到後端的數據包。
  • 然後使用DSR通過邊緣路由器將數據包從後端直接發送到客戶端。
  • L4負載平衡器使用的實際一致哈希算法是一個積極研究的領域。主要圍繞平衡負載進行權衡,盡量減少延遲,盡量減少後端更改期間的中斷,
  • 並儘量減少內存開銷。有關此主題的完整討論超出了本文的範圍。

L7負載平衡技術的當前狀態


確實。最近幾年,L7負載平衡器/代理開發領域出現了復甦。隨著分佈式系統中微服務架構的不斷推進,這種情況非常好。從根本上講,當使用頻率更高時,固有故障網絡變得更加難以有效運行。此外,自動擴展,容器調度等的出現意味著靜態文件中靜態IP的配置日期早已不復存在。系統不僅更多地利用網絡,而且它們變得更加動態,需要負載平衡器中的新功能。在本節中,本文將簡要概述在現代L7負載平衡器中發展最為迅速的領域。

協議支持

現代L7負載平衡器為許多不同的協議添加了明確的支持。負載平衡器對應用程序流量的了解越多,就可觀察性輸出,高級負載平衡和路由等方面而言,它可以做的更複雜的事情。例如,在撰寫本文時,Envoy明確支持L7協議解析和路由用於HTTP / 1,HTTP2,gRPC,Redis,MongoDB和DynamoDB。未來可能會增加更多的協議,包括MySQL和Kafka。

動態配置

如上所述,分佈式系統日益動態的性質需要並行投資來創建動態和反應式控制系統。 Istio就是這樣一個系統的一個例子。有關此主題的更多信息,請參閱作者在服務網格數據平面與控制平面上的文章

高級負載平衡

L7負載平衡器現在通常內置對高級負載平衡功能的支持,例如超時,重試,速率限制,斷路,投影,緩衝,基於內容的路由等。

觀測性

如上面有關常規負載平衡器功能的部分所述,正在部署的日益動態的系統越來越難以偵錯。強大的協議特定可觀察性輸出可能是現代L7負載平衡器提供的最重要的特性。任何L7負載平衡解決方案現在都需要輸出數字統計信息,分佈式跟踪和可自定義日誌記錄。

可擴展性

現代L7負載平衡器的用戶通常希望輕鬆擴展它們以添加自定義功能。這可以通過編寫加載到負載平衡器的可插入過濾器來完成。許多負載平衡器也支持腳本,通常通過Lua實現。

容錯

我寫了一些關於L4負載平衡器容錯的內容。 L7負載平衡器的容錯性如何?一般來說,我們將L7負載平衡器視為可消耗和無狀態。使用商品軟體可使L7負載平衡器輕鬆橫向縮放。此外,L7負載平衡器執行的處理和狀態跟踪比L4複雜得多。試圖建立一個L7負載平衡器的HA配對在技術上是可行的,但這將是一項重大任務。 總體而言,在L4和L7負載平衡領域,業界正在從HA配對轉向橫向可擴展系統,這些系統通過一致的哈希聚合。

更多

L7負載平衡器正在以驚人的速度發展。有關Envoy提供的示例,請參閱Envoy的架構概述

全球負載平衡和集中控制平面(Global load balancing and the centralized control plane)

圖13: 全球負載平衡
負載平衡的未來將越來越多地將單個負載平衡器視為商品設備。在我看來,真正的創新和商業機會都在控制層面。圖13顯示了一個全局負載平衡系統的例子。在這個例子中,幾個不同的事情正在發生:

  • 每個邊車代理(Sidecar proxy)與三個不同區域(A,B和C)中的後端進行通信。
  • 如圖所示,90%的流量正在發送到C區,而5%的流量正在發送到A區和B區。
  • 邊車代理和後端都向全球負載平衡器報告週期性狀態。這讓全局負載平衡器做出延遲,成本,負載,當前故障等的決策。
  • 全局負載平衡器使用當前路由信息定期配置每個邊車代理。

全球負載平衡器將越來越能夠完成複雜的任務,而不需要單獨的負載平衡器自己完成。例如:
  • 使用機器學習和神經網絡檢測和減輕流量異常,包括DDoS攻擊。
  • 自動檢測並繞過區域故障。
  • 應用全球安全和路由策略。
  • 提供集中的用戶界面和可視化,使工程師能夠綜合了解和操作整個分佈式系統。
為了實現全球負載平衡,用作數據平面的負載平衡器必須具有復雜的動態配置功能。有關此主題的更多訊息,請參閱Envoy的通用數據平面API以及服務網格數據平面與控制平面的文章



從硬件到軟件的演變


到目前為止,這篇文章只是簡單地提到了硬體和軟體和在歷史L4負載平衡器HA對比的背景下。在業界中這塊的趨勢是什麼?


以前的推文是一個有點誇張幽默,但仍然相當好的趨勢,這是:
  • 歷史上,路由器和負載平衡器已經作為非常昂貴的專有硬件提供。
  • 越來越多的專有L3 / L4網絡設備正在被商用服務器硬體,商用網卡和基於IPVS,DPDK和fd.io等框架的專業軟體解決方案所取代。價格低於5K美元的現代數據中心機器可以使用Linux和使用DPDK編寫的定制用戶空間應用程序輕鬆飽和具有非常小數據包的80Gbps NIC。與此同時,廉價和基本的路由器/交換機ASIC可以以驚人的聚合帶寬和數據包速率進行ECMP路由選擇,正在被打包為商用路由器。
  • 像NGINX,HAProxy和Envoy這樣先進的L7軟體負載平衡器也在快速迭代並侵入之前像F5這樣的供應商領域。因此,L7負載平衡器也在積極地向商品軟件解決方案邁進。
  • 與此同時,整個行業向主流雲提供商推動IaaS,CaaS和FaaS的發展,這意味著越來越多的工程師需要了解物理網絡的工作原理(這些是“黑魔法“和”我們不再需要造輪子的部分)。

總結

總而言之,這篇文章的主要內容是:
  • 負載平衡器是現代分佈式系統中的關鍵組件。
  • 有兩種一般類型的負載平衡器:L4和L7。
  • L4和L7負載平衡器都與現代架構相關。
  • L4負載平衡器正朝著水平可擴展的分佈式一致散​​列解決方案邁進。
  • 由於動態微服務體系結構的激增,L7負載平衡器最近投入巨資。
  • 全局負載平衡和控制平面與數據平面之間的分離是負載平衡的未來,並且將發現大多數未來的創新和商業機會。
  • 這個行業正在積極地轉向用於網路解決方案的商品OSS硬體和軟體。我相信傳統的負載平衡廠商如F5將首先被OSS軟件和雲供應商所取代。傳統的路由器/交換機廠商如Arista / Cumulus /等。我認為在內部部署上有更大的跑道,但最終也會被公共雲供應商和他們自己生產的物理網路所取代。
總體來說,我認為這是一個計算機網路的迷人時刻!對大多數系統而言,採用OSS和軟體的做法正在將迭代速度提高數個數量級。此外,隨著分佈式系統通過“無服務器”繼續向動態發展,底層網路和負載平衡系統的複雜性將需要相應增加。

留言

  1. Hi Friend!
    If you have a moment, please take a look at my site: salt lake city escorts Have a great day!

    回覆刪除
  2. Good topic for me and Avyukta intellicall is the best call center services and solutions provider in India. Read our call center case studies. For more information visit on my site www.dialervendor.com and call us: +91-8560000600.

    Thanks & Regards
    Avyukta intellicall.

    回覆刪除

張貼留言

這個網誌中的熱門文章

Grafana K6

Linux 事件驅動筆記