gRPC Load Balancing

gRPC Load Balancing

翻譯自://grpc.io/blog/grpc-load-balancing/

這是gRPC負載均衡的第一篇,後續會給出基於golang XDS服務發現的例子,了解golang XDS的工作原理。

本文描述了在部署gRPC時可能會採用的幾種負載均衡場景。

大規模gRPC部署下,通常會有大量相同的後端實例以及大量客戶端。由於每個服務的容量是有限的,因此會使用負載均衡在可用的伺服器之間均衡來自客戶端的請求。

為什麼使用gRPC

gRPC是一個先進的RPC協議,它是基於HTTP/2實現的。HTTP/2是一個7層協議,運行在TCP協議之上。相比傳統的HTTP/REST/JSON機制,gRPC有很多優點,如:

  1. 它使用了二進位協議(HTTP/2)
  2. 在一個連接(HTTP/2)上復用多個請求
  3. 頭部壓縮(HTTP/2)
  4. 強類型服務和消息定義(Protobuf)
  5. 為多種語言實現了常用的客戶端/伺服器庫

此外,gRPC無縫集成了如服務發現,命名解析,負載均衡,追蹤和監控等生態組件。

負載均衡選項

代理負載均衡還是客戶端側負載均衡?

註:某些文章中會把代理負載均衡稱為服務端側負載均衡。

使用代理負載均衡還是客戶端測負載均衡是一個主要的架構上的抉擇。使用代理負載均衡時,客戶端會像負載均衡(LB)代理髮起RPCs,LB會將RPC請求分發到實現了該調用的可用的後端伺服器上。LB會持續跟蹤每個後端,並實現公平分配負載的演算法。客戶端本身並不知道後端服務的資訊。客戶端可能是不可信的。該架構通常用於面向用戶的服務,開放網路下的客戶端可以連接到數據中心的伺服器上,如下圖所示,這種場景下,客戶端會像LB發生請求(#1),LB將請求分發給某個後端(#2),最後後端將結果返回給LB(#3)。

當使用客戶端側的負載均衡時,客戶端會知道多個後端伺服器的情況,然後為每個RPC從中選擇一個處理伺服器。客戶端會從後端伺服器接收RPC結果,且客戶端會實現負載均衡演算法。在更簡單的配置中,可以不考慮伺服器負載,客戶端僅需要在可用的伺服器之間進行輪詢即可。如下圖,客戶端會向指定的伺服器發送請求(#1),後端會相應負載資訊(#2),客戶端通常會在相同的連接上執行RPC。客戶端負責更新內部狀態。

下表展示了每種模型的優劣勢:

Proxy Client Side
優勢 簡化客戶端配置
客戶端側無需了解後端資訊
可以配合不可信的客戶端
由於消除了多餘的條數,提升了性能
劣勢 LB位於數據路徑上
較高的延遲
LB的吞吐量可能會限制可擴展性
複雜的客戶端
客戶端需要持續跟蹤服務端的負載和健康情況
客戶端需要實現負載均衡
每個語言的實現和維護負擔
需要可信的客戶端,或信任邊界需要由備用的LB進行處理

代理負載均衡選項

代理負載均衡可以工作在L3/L4或L7。在傳輸層的負載均衡,服務端會終止TCP連接,然後打開到選擇的後端的另外一個連接。應用數據(HTTP/2個gRPC幀)會在客戶端連接和後端連接之間進行拷貝。相比L7 LB,L3/L4 LB僅會進行很少的處理,且消耗的資源也更少。

在使用L7負載均衡時,LB會終結連接並解析HTTP/2協議。LB會檢查每個請求並根據請求內容將其分配給一個後端。例如,帶session cookie的HTTP首部可以關聯一個特定的後端,因此該session的所有請求都會被該後端處理。一旦LB選擇了一個合適的後端,它會跟這個後端創建一條新的HTTP/2連接,然後轉發接收到的客戶端到該後端的HTTP/2流。使用HTTP/2,LB可以將一個客戶端的流分配給多個後端。

L3/L4 vs L7
使用場景 建議
RPC的負載在連接之間變化很大 使用應用層的LB
存儲或計算親和性比較重要 使用應用層LB,並使用cookie類似的功能來路由請求到正確的後端
減小代理的資源利用率比使用其特性更重要 使用L3/L4 LB
注重延遲 使用L3/L4 LB

客戶端側的LB選項

胖客戶端

胖客戶端方式意味著在客戶端實現負載均衡。客戶端負責持續跟蹤可用的伺服器,以及伺服器負載,並實現選擇伺服器的演算法。客戶端通常會集成與其他基礎設施通訊的庫,如服務發現,命名解析,配額管理等。

備用負載均衡

註:備用負載均衡也被稱為外部負載均衡或單路並聯負載均衡

使用備用負載均衡時,會將其實現為一個特定的LB伺服器。客戶端或請求備用LB,備用LB會返回最合適的伺服器。在後備LB中實現了跟蹤伺服器狀態和LB演算法實現的繁重工作。注意,客戶端可能會選擇在LB中實現的複雜演算法之上實現簡單演算法。gRPC為該模型定義了一個協議,用於客戶端和LB之間的通訊,參見 doc

下圖展示了這種方式。客戶端從備用LB中獲得至少一個地址(#1),客戶端會使用該地址發起RPC(#2),伺服器會將結果發送給LB(#3),備用LB會與其他基礎設施通訊,如命名解析,服務發現等(#4)。

建議和最佳實現

基於特定部署和限制,建議如下:

配置 建議
客戶端和伺服器之間流量很高
客戶端可信
使用胖客戶端負載均衡
客戶端側使用ZooKeeper/Etcd/Consul/Eureka,ZooKeeper example
傳統配置–很多客戶端連接到位於代理之後的服務
伺服器和客戶端之間需要配置信任邊界
代理負載均衡
L3/L4 LB,使用GCLB
L3/L4 LB,使用haproxy – config file
Nginx
如果需要會話粘性,可以使用Envoy L7 LB作為代理
微服務,數據中心有N個客戶端,N個伺服器
很高的性能要求(低延遲,大流量)
客戶端可能是不可信的
備用負載均衡
客戶端側LB,使用 gRPC-LB protocol
現有的服務網格,例如使用Linkerd或Istio進行的設置 Service Mesh
使用內置的LB,如 Istio, 或Envoy.
Tags: