零、從橫向擴展說起
從單機擴展到多機,面臨的第一個問題就是這些機器如何協同工作,即如何調度請求:
[caption id="attachment_2103" align="alignnone" width="625"]
load balancer dispatcher[/caption]
P.S. 關於橫向擴展與縱向擴展的詳細信息,見 Scalability_系統設計筆記 1
一、負載均衡器
多服務器下的請求調度機制稱為負載均衡(Load balancing),調度器(Dispatcher)即負載均衡器(Load balancer):

其主要作用是根據既定策略(如隨機、輪流)將客戶端請求分發給各個服務器:
The fundamental feature of a load balancer is to be able to distribute incoming requests over a number of backend servers in the cluster according to a scheduling algorithm.
有助於:
-
防止請求到達不可用的服務器
-
防止資源過載
-
消除單點故障,提升可用性
此外,還可以用於:
-
SSL termination:處理 SSL 連接,將加密解密的工作前置到調度層
-
會話保留(Session persistence):集中處理會話,避免切換服務器造成會話狀態丟失
也就是說,多機場景下,必須要有一個負責分發/調度請求的負載均衡器,那麼,接下來的問題是應該在哪一層實現負載均衡機制
二、實現思路
考慮一個 HTTP 請求從客戶端到服務器的通信過程,可以簡單劃分為 3 個階段:
-
出發:客戶端發出請求
-
途中:請求經網絡傳輸
-
到達:服務器收到請求
對請求進行分發/調度,就是要想辦法(按既定策略)改變請求的目的地,那麼,至少有 3 種思路:
-
出發前:在請求經網絡傳輸之前,就確定最終目的地,例如 DNS 負載均衡、客戶端負載均衡
-
傳輸中:在網絡傳輸的某些環節改變目的地,例如 4 層負載均衡
-
到達後:在請求抵達服務器後,進行二次分發,例如 7 層負載均衡
三、DNS 負載均衡
客戶端要向服務器發起請求,首先要知道服務器的 IP 地址,通過 DNS 來查詢:

DNS 維護著域名與 IP 地址之間的映射關係,因此可以在這裡實現負載均衡策略,將請求指向目標服務器(的 IP 地址),例如:
-
輪流分發:添加一系列 A 記錄,將同一域名指向多個不同的 IP 地址即可,稱為 round-robin DNS
-
隨機分發:採用支持 多值應答路由策略 的 DNS 服務
簡單易用,但缺陷也很明顯:
-
可靠性沒有保障:DNS 並不檢查服務器的可用性,即便目標服務器 down 掉了或者無法訪問了,也返回其 IP 地址
-
更新不及時:DNS 的解析結果往往會被層層緩存,記錄更新無法立即生效
P.S. 關於 DNS 負載均衡的更多信息,見 What Is DNS Load Balancing?
四、客戶端負載均衡
同理,把服務器 IP 地址選擇機制拿到客戶端來實現,就叫客戶端負載均衡
由客戶端自行選擇目標服務器的 IP 地址(不再通過 DNS 查詢):
[caption id="attachment_2105" align="alignnone" width="445"]
client-side load balancing[/caption]
例如,向客戶端提供服務器 IP 列表,客戶端發起請求之前隨機選取一個 IP,就能達到隨機分發的目的
比起 DNS 負載均衡,客戶端不存在緩存的問題,而且能夠進行更精細的控制,比如檢查服務可用性,並從中選取可用的 IP 地址
五、OSI 七層模型
請求從客戶端發出之後,接著通過網絡進行傳輸
OSI(Open System Interconnect)參考模型 將網絡通信分為 7 個抽象層:
自下而上,依次為:
-
物理層(第 1 層):通過物理介質傳輸原始比特流,即物理信號(Symbol)
-
數據鏈路層(第 2 層):提供可靠的節點間數據幀(Frame)傳輸機制,具體工作包括 MAC 尋址
-
網絡層(第 3 層):決定數據包(Packet)傳輸將採取的物理路徑,支持 IP、ARP 等協議,具體工作包括 IP 尋址、路由和流量控制
-
傳輸層(第 4 層):提供可靠的報文(Datagram)傳輸機制,支持 TCP、UDP 等傳輸協議,具體工作包括
-
會話層(第 5 層):負責管理會話,以支持通過多次傳輸連續交換信息
-
表現層(第 6 層):將來自網絡服務的數據翻譯成應用層可用的格式,具體工作包括字符編碼轉換、數據壓縮、加密解密等
-
應用層(第 7 層):提供高級 API 的人機交互層,應用能夠通過該層訪問網絡服務,如資源共享、遠程文件訪問等
其中,第 1 層是原始數據,第 2 層確定目標機器的 MAC 地址,第 3 層確定終點的 IP 地址,以及途經的具體路線,到第 4 層,要根據傳輸協議確定目標端口號,第 5~7 層不關心終點,因為 IP 地址 + MAC 地址 + 端口號已經唯一確定了目標應用程序
也就是說,一個 HTTP 請求必須經由這些層才能到達目標服務器,那麼,理論上,在第 2~7 層中的任意一層都有機會變更終點,實現負載均衡
而常見的負載均衡機制多實現在第 4 層和第 7 層,這是為什麼呢?
六、2 層、3 層負載均衡
-
2 層負載均衡:根據源/目標 MAC 地址進行分發,例如將虛擬 MAC 地址根據既定策略映射到實際 MAC 地址
-
3 層負載均衡:根據源/目標 IP 地址,以及第 2 層信息進行分發,例如解析虛擬 IP(Virtual IP address)
越靠近底層,所能用來進行分發決策的信息越少,所以 2 層負載均衡的實際用途有限,常見的只有冗餘網關協議(如 GLBP、VRRP)和鏈路聚合(Link aggregation,也叫 etherchannel)等,具體見 How is load balancing achieved with layer 2 devices?
七、4 層負載均衡
4 層負載均衡基於傳輸層(第 4 層)信息進行請求分發,包括源/目標 IP 地址,以及數據包頭部的端口號,但不考慮數據包內容:
Layer 4 load balancing uses information defined at the networking transport layer (Layer 4) as the basis for deciding how to distribute client requests across a group of servers. For Internet traffic specifically, a Layer 4 load balancer bases the load-balancing decision on the source and destination IP addresses and ports recorded in the packet header, without considering the contents of the packet.
客戶端將負載均衡器的 IP 地址作為目標 IP 地址發起請求,4 層負載均衡器收到請求後,對數據包進行 NAT 轉換,將目標 IP 地址修改成實際服務器的地址,在將服務器響應轉發給客戶端之前,負載均衡器再將源 IP 地址改成自身的 IP 地址。類似的,對數據包中的源/目標端口號也以這種方式進行修改
P.S. 第 4 層負載均衡器通常是專用的硬件設備,NAT 操作可能會由專用芯片來完成
與更複雜的 7 層負載均衡相比,4 層負載均衡所需的計算更少,但在目前的硬件條件下,由此帶來的性能優勢已經不重要了
P.S.嚴格來講,4 層負載均衡應該叫 3/4 層負載均衡,因為結合了第 3 層的 IP 地址和第 4 層的端口號信息
八、7 層負載均衡
7 層負載均衡根據應用層協議信息(如 HTTP 頭)以及數據包內容信息進行分發,包括 URL、數據類型、Cookie 信息等:
Layer 7 load balancers base their routing decisions on various characteristics of the HTTP header and on the actual contents of the message, such as the URL, the type of data (text, video, graphics), or information in a cookie.
比起 4 層負載均衡,7 層負載均衡可以讀取請求和響應內容,所需的計算雖然更多,但不見得比 4 層負載均衡性能更差,因為擁有更全面的上下文信息,可以在此基礎上進行更聰明的全局決策(比如剔除慢速連接、重定向超時請求),甚至還能對內容進行優化(比如壓縮),從而提高性能
P.S.嚴格來講,7 層負載均衡應該叫 5~7 層負載均衡,因為結合了 OSI 模型中 5~7 層的相關信息:
[caption id="attachment_2110" align="alignnone" width="800"]
TCP/IP model and OSI model[/caption]
暫無評論,快來發表你的看法吧