剛進來的小伙伴說負載均衡,還是太年輕了!
圖片來自 Pexels
負載均衡由來
隨著業(yè)務(wù)流量越來越大,單臺服務(wù)器無論如何優(yōu)化,無論采用多好的硬件,總會有性能天花板,當(dāng)單服務(wù)器的性能無法滿足業(yè)務(wù)需求時,就需要把多臺服務(wù)器組成集群系統(tǒng)提高整體的處理性能。
基于上述需求,我們要使用統(tǒng)一的流量入口來對外提供服務(wù),本質(zhì)上就是需要一個流量調(diào)度器,通過均衡的算法,將用戶大量的請求流量均衡地分發(fā)到集群中不同的服務(wù)器上。這其實就是我們今天要說的負載均衡。
使用負載均衡可以給我們帶來的幾個好處:
- 提高了系統(tǒng)的整體性能
- 提高了系統(tǒng)的擴展性
- 提高了系統(tǒng)的可用性
負載均衡類型
廣義上的負載均衡器大概可以分為 3 類,包括:
- DNS 方式實現(xiàn)負載均衡
- 硬件負載均衡
- 軟件負載均衡
DNS 實現(xiàn)負載均衡
DNS 實現(xiàn)負載均衡是最基礎(chǔ)簡單的方式。一個域名通過 DNS 解析到多個 IP,每個 IP 對應(yīng)不同的服務(wù)器實例,這樣就完成了流量的調(diào)度,雖然沒有使用常規(guī)的負載均衡器,但實現(xiàn)了簡單的負載均衡功能。
通過 DNS 實現(xiàn)負載均衡的方式,最大的優(yōu)點就是實現(xiàn)簡單,成本低,無需自己開發(fā)或維護負載均衡設(shè)備。
不過存在一些缺點:
①服務(wù)器故障切換延遲大,服務(wù)器升級不方便
我們知道 DNS 與用戶之間是層層的緩存,即便是在故障發(fā)生時及時通過 DNS 修改或摘除故障服務(wù)器,但中間經(jīng)過運營商的 DNS 緩存,且緩存很有可能不遵循 TTL 規(guī)則,導(dǎo)致 DNS 生效時間變得非常緩慢,有時候一天后還會有些許的請求流量。
②流量調(diào)度不均衡,粒度太粗
DNS 調(diào)度的均衡性,受地區(qū)運營商 LocalDNS 返回 IP 列表的策略有關(guān)系,有的運營商并不會輪詢返回多個不同的 IP 地址。
另外,某個運營商 LocalDNS 背后服務(wù)了多少用戶,這也會構(gòu)成流量調(diào)度不均的重要因素。
③流量分配策略太簡單,支持的算法太少
DNS 一般只支持 rr 的輪詢方式,流量分配策略比較簡單,不支持權(quán)重、Hash 等調(diào)度算法。
④DNS 支持的 IP 列表有限制
我們知道 DNS 使用 UDP 報文進行信息傳遞,每個 UDP 報文大小受鏈路的 MTU 限制,所以報文中存儲的 IP 地址數(shù)量也是非常有限的,阿里 DNS 系統(tǒng)針對同一個域名支持配置 10 個不同的 IP 地址。
實際上生產(chǎn)環(huán)境中很少使用這種方式來實現(xiàn)負載均衡,畢竟缺點很明顯。文中之所以描述 DNS 負載均衡方式,是為了能夠更清楚地解釋負載均衡的概念。
像 BAT 體量的公司一般會利用 DNS 來實現(xiàn)地理級別的全局負載均衡,實現(xiàn)就近訪問,提高訪問速度,這種方式一般是入口流量的基礎(chǔ)負載均衡,下層會有更專業(yè)的負載均衡設(shè)備實現(xiàn)的負載架構(gòu)。
硬件負載均衡
硬件負載均衡是通過專門的硬件設(shè)備來實現(xiàn)負載均衡功能,是專用的負載均衡設(shè)備。目前業(yè)界典型的硬件負載均衡設(shè)備有兩款:F5 和 A10。
這類設(shè)備性能強勁、功能強大,但價格非常昂貴,一般只有土豪公司才會使用此類設(shè)備,中小公司一般負擔(dān)不起,業(yè)務(wù)量沒那么大,用這些設(shè)備也是挺浪費的。
硬件負載均衡的優(yōu)點:
- 功能強大:全面支持各層級的負載均衡,支持全面的負載均衡算法。
- 性能強大:性能遠超常見的軟件負載均衡器。
- 穩(wěn)定性高:商用硬件負載均衡,經(jīng)過了良好的嚴(yán)格測試,經(jīng)過大規(guī)模使用,穩(wěn)定性高。
- 安全防護:還具備防火墻、防 DDoS 攻擊等安全功能,以及支持 SNAT 功能。
硬件負載均衡的缺點也很明顯:
- 價格貴
- 擴展性差,無法進行擴展和定制
- 調(diào)試和維護比較麻煩,需要專業(yè)人員
軟件負載均衡
軟件負載均衡,可以在普通的服務(wù)器上運行負載均衡軟件,實現(xiàn)負載均衡功能。
目前常見的有 Nginx、HAproxy、LVS,其中的區(qū)別如下:
- Nginx:七層負載均衡,支持 HTTP、E-mail 協(xié)議,同時也支持 4 層負載均衡。
- HAproxy:支持七層規(guī)則的,性能也很不錯。OpenStack 默認使用的負載均衡軟件就是 HAproxy。
- LVS:運行在內(nèi)核態(tài),性能是軟件負載均衡中最高的,嚴(yán)格來說工作在三層,所以更通用一些,適用各種應(yīng)用服務(wù)。
軟件負載均衡的優(yōu)點:
- 易操作:無論是部署還是維護都相對比較簡單。
- 便宜:只需要服務(wù)器的成本,軟件是免費的。
- 靈活:4 層和 7 層負載均衡可以根據(jù)業(yè)務(wù)特點進行選擇,方便進行擴展和定制功能。
負載均衡 LVS
軟件負載均衡主要包括:Nginx、HAproxy 和 LVS,三款軟件都比較常用。
四層負載均衡基本上都會使用 LVS,據(jù)了解 BAT 等大廠都是 LVS 重度使用者,就是因為 LVS 非常出色的性能,能為公司節(jié)省巨大的成本。
LVS,全稱 Linux Virtual Server 是由國人章文嵩博士發(fā)起的一個開源的項目,在社區(qū)具有很大的熱度,是一個基于四層、具有強大性能的反向代理服務(wù)器。
它現(xiàn)在是標(biāo)準(zhǔn)內(nèi)核的一部分,它具備可靠性、高性能、可擴展性和可操作性的特點,從而以低廉的成本實現(xiàn)最優(yōu)的性能。
Netfilter 基礎(chǔ)原理
LVS 是基于 Linux 內(nèi)核中 netfilter 框架實現(xiàn)的負載均衡功能,所以要學(xué)習(xí) LVS 之前必須要先簡單了解 netfilter 基本工作原理。
netfilter 其實很復(fù)雜,平時我們說的 Linux 防火墻就是 netfilter,不過我們平時操作的都是 iptables,iptables 只是用戶空間編寫和傳遞規(guī)則的工具而已,真正工作的是 netfilter。
通過下圖可以簡單了解下 netfilter 的工作機制:
netfilter 是內(nèi)核態(tài)的 Linux 防火墻機制,作為一個通用、抽象的框架,提供了一整套的 hook 函數(shù)管理機制,提供諸如數(shù)據(jù)包過濾、網(wǎng)絡(luò)地址轉(zhuǎn)換、基于協(xié)議類型的連接跟蹤的功能。
通俗點講,就是 netfilter 提供一種機制,可以在數(shù)據(jù)包流經(jīng)過程中,根據(jù)規(guī)則設(shè)置若干個關(guān)卡(hook 函數(shù))來執(zhí)行相關(guān)的操作。
netfilter 總共設(shè)置了 5 個點,包括:
- PREROUTING:剛剛進入網(wǎng)絡(luò)層,還未進行路由查找的包,通過此處。
- INPUT:通過路由查找,確定發(fā)往本機的包,通過此處。
- FORWARD:經(jīng)路由查找后,要轉(zhuǎn)發(fā)的包,在 POST_ROUTING 之前。
- OUTPUT:從本機進程剛發(fā)出的包,通過此處。
- POSTROUTING:進入網(wǎng)絡(luò)層已經(jīng)經(jīng)過路由查找,確定轉(zhuǎn)發(fā),將要離開本設(shè)備的包,通過此處。
當(dāng)一個數(shù)據(jù)包進入網(wǎng)卡,經(jīng)過鏈路層之后進入網(wǎng)絡(luò)層就會到達 PREROUTING,接著根據(jù)目標(biāo) IP 地址進行路由查找,如果目標(biāo) IP 是本機,數(shù)據(jù)包繼續(xù)傳遞到 INPUT 上,經(jīng)過協(xié)議棧后根據(jù)端口將數(shù)據(jù)送到相應(yīng)的應(yīng)用程序。
應(yīng)用程序處理請求后將響應(yīng)數(shù)據(jù)包發(fā)送到 OUTPUT 上,最終通過 POSTROUTING 后發(fā)送出網(wǎng)卡。
如果目標(biāo) IP 不是本機,而且服務(wù)器開啟了 forward 參數(shù),就會將數(shù)據(jù)包遞送給 FORWARD 上,最后通過 POSTROUTING 后發(fā)送出網(wǎng)卡。
LVS 基礎(chǔ)原理
LVS 是基于 netfilter 框架,主要工作于 INPUT 鏈上,在 INPUT 上注冊 ip_vs_in HOOK 函數(shù),進行 IPVS 主流程。
大概原理如上圖所示:
- 當(dāng)用戶訪問 www.sina.com.cn 時,用戶數(shù)據(jù)通過層層網(wǎng)絡(luò),最后通過交換機進入 LVS 服務(wù)器網(wǎng)卡,并進入內(nèi)核網(wǎng)絡(luò)層。
- 進入 PREROUTING 后經(jīng)過路由查找,確定訪問的目的 VIP 是本機 IP 地址,所以數(shù)據(jù)包進入到 INPUT 鏈上。
- LVS 是工作在 INPUT 鏈上,會根據(jù)訪問的 IP:Port 判斷請求是否是 LVS 服務(wù),如果是則進行 LVS 主流程,強行修改數(shù)據(jù)包的相關(guān)數(shù)據(jù),并將數(shù)據(jù)包發(fā)往 POSTROUTING 鏈上。
- POSTROUTING 上收到數(shù)據(jù)包后,根據(jù)目標(biāo) IP 地址(后端真實服務(wù)器),通過路由選路,將數(shù)據(jù)包最終發(fā)往后端的服務(wù)器上。
開源 LVS 版本有 3 種工作模式,每種模式工作原理都不同,每種模式都有自己的優(yōu)缺點和不同的應(yīng)用場景。
包括以下三種模式:
- DR 模式
- NAT 模式
- Tunnel 模式
這里必須要提另外一種模式是 FullNAT,這個模式在開源版本中是模式?jīng)]有的。
這個模式最早起源于百度,后來又在阿里發(fā)揚光大,由阿里團隊開源,代碼地址如下:
- https://github.com/alibaba/lvs
LVS 官網(wǎng)也有相關(guān)下載地址,不過并沒有合進到內(nèi)核主線版本。后面會有專門章節(jié)詳細介紹 FullNAT 模式。
下邊分別就 DR、NAT、Tunnel 模式分別詳細介紹原理。
DR 模式實現(xiàn)原理
LVS 基本原理圖中描述的比較簡單,表述的是比較通用流程。下邊會針對 DR 模式的具體實現(xiàn)原理,詳細的闡述 DR 模式是如何工作的。
其實 DR 是最常用的工作模式,因為它的強大的性能。下邊試圖以某個請求和響應(yīng)數(shù)據(jù)流的過程來描述 DR 模式的工作原理。
實現(xiàn)原理過程
①當(dāng)客戶端請求 www.sina.com.cn 主頁,請求數(shù)據(jù)包穿過網(wǎng)絡(luò)到達 Sina 的 LVS 服務(wù)器網(wǎng)卡:源 IP 是客戶端 IP 地址 CIP,目的 IP 是新浪對外的服務(wù)器 IP 地址,也就是 VIP。
此時源 MAC 地址是 CMAC,其實是 LVS 連接的路由器的 MAC 地址(為了容易理解記為 CMAC),目標(biāo) MAC 地址是 VIP 對應(yīng)的 MAC,記為 VMAC。
②數(shù)據(jù)包經(jīng)過鏈路層到達 PREROUTING 位置(剛進入網(wǎng)絡(luò)層),查找路由發(fā)現(xiàn)目的 IP 是 LVS 的 VIP,就會遞送到 INPUT 鏈上,此時數(shù)據(jù)包 MAC、IP、Port 都沒有修改。
③數(shù)據(jù)包到達 INPUT 鏈,INPUT 是 LVS 主要工作的位置。此時 LVS 會根據(jù)目的 IP 和 Port 來確認是否是 LVS 定義的服務(wù)。
如果是定義過的 VIP 服務(wù),就會根據(jù)配置信息,從真實服務(wù)器列表 中選擇一個作為 RS1,然后以 RS1 作為目標(biāo)查找 Out 方向的路由,確定一下跳信息以及數(shù)據(jù)包要通過哪個網(wǎng)卡發(fā)出。最后將數(shù)據(jù)包投遞到 OUTPUT 鏈上。
④數(shù)據(jù)包通過 POSTROUTING 鏈后,從網(wǎng)絡(luò)層轉(zhuǎn)到鏈路層,將目的 MAC 地址修改為 RealServer 服務(wù)器 MAC 地址,記為 RMAC;而源 MAC 地址修改為 LVS 與 RS 同網(wǎng)段的 selfIP 對應(yīng)的 MAC 地址,記為 DMAC。
此時,數(shù)據(jù)包通過交換機轉(zhuǎn)發(fā)給了 RealServer 服務(wù)器(注:為了簡單圖中沒有畫交換機)。
⑤請求數(shù)據(jù)包到達后端真實服務(wù)器后,鏈路層檢查目的 MAC 是自己網(wǎng)卡地址。
到了網(wǎng)絡(luò)層,查找路由,目的 IP 是 VIP(lo 上配置了 VIP),判定是本地主機的數(shù)據(jù)包,經(jīng)過協(xié)議??截愔翍?yīng)用程序(比如 nginx 服務(wù)器),nginx 響應(yīng)請求后,產(chǎn)生響應(yīng)數(shù)據(jù)包。
然后以 CIP 查找出方向的路由,確定下一跳信息和發(fā)送網(wǎng)卡設(shè)備信息。此時數(shù)據(jù)包源、目的 IP 分別是 VIP、CIP。
而源 MAC 地址是 RS1 的 RMAC,目的 MAC 是下一跳(路由器)的 MAC 地址,記為 CMAC(為了容易理解,記為 CMAC)。
然后數(shù)據(jù)包通過 RS 相連的路由器轉(zhuǎn)發(fā)給真正客戶端,完成了請求響應(yīng)的全過程。
從整個過程可以看出,DR 模式 LVS 邏輯比較簡單,數(shù)據(jù)包通過直接路由方式轉(zhuǎn)發(fā)給后端服務(wù)器,而且響應(yīng)數(shù)據(jù)包是由 RS 服務(wù)器直接發(fā)送給客戶端,不經(jīng)過 LVS。
我們知道通常請求數(shù)據(jù)包會比較小,響應(yīng)報文較大,經(jīng)過 LVS 的數(shù)據(jù)包基本上都是小包,所以這也是 LVS 的 DR 模式性能強大的主要原因。
優(yōu)缺點和使用場景
DR 模式的優(yōu)點:
- 響應(yīng)數(shù)據(jù)不經(jīng)過 lvs,性能高
- 對數(shù)據(jù)包修改小,信息保存完整(攜帶客戶端源 IP)
DR 模式的缺點:
- lvs 與 rs 必須在同一個物理網(wǎng)絡(luò)(不支持跨機房)
- 服務(wù)器上必須配置 lo 和其它內(nèi)核參數(shù)
- 不支持端口映射
DR 模式的使用場景:如果對性能要求非常高,可以首選 DR 模式,而且可以透傳客戶端源 IP 地址。
NAT 模式實現(xiàn)原理
lvs 的第 2 種工作模式是 NAT 模式,下圖詳細介紹了數(shù)據(jù)包從客戶端進入 lvs 后轉(zhuǎn)發(fā)到 rs,后經(jīng) rs 再次將響應(yīng)數(shù)據(jù)轉(zhuǎn)發(fā)給 lvs,由 lvs 將數(shù)據(jù)包回復(fù)給客戶端的整個過程。
實現(xiàn)原理與過程
①用戶請求數(shù)據(jù)包經(jīng)過層層網(wǎng)絡(luò),到達 lvs 網(wǎng)卡,此時數(shù)據(jù)包源 IP 是 CIP,目的 IP 是 VIP。
②經(jīng)過網(wǎng)卡進入網(wǎng)絡(luò)層 prerouting 位置,根據(jù)目的 IP 查找路由,確認是本機 IP,將數(shù)據(jù)包轉(zhuǎn)發(fā)到 INPUT 上,此時源、目的 IP 都未發(fā)生變化。
③到達 lvs 后,通過目的 IP 和目的 port 查找是否為 IPVS 服務(wù)。
若是 IPVS 服務(wù),則會選擇一個 RS 作為后端服務(wù)器,將數(shù)據(jù)包目的 IP 修改為 RIP,并以 RIP 為目的 IP 查找路由信息,確定下一跳和出口信息,將數(shù)據(jù)包轉(zhuǎn)發(fā)至 output 上。
④修改后的數(shù)據(jù)包經(jīng)過 postrouting 和鏈路層處理后,到達 RS 服務(wù)器,此時的數(shù)據(jù)包源 IP 是 CIP,目的 IP 是 RIP。
⑤到達 RS 服務(wù)器的數(shù)據(jù)包經(jīng)過鏈路層和網(wǎng)絡(luò)層檢查后,被送往用戶空間 nginx 程序。
nginx 程序處理完畢,發(fā)送響應(yīng)數(shù)據(jù)包,由于 RS 上默認網(wǎng)關(guān)配置為 lvs 設(shè)備 IP,所以 nginx 服務(wù)器會將數(shù)據(jù)包轉(zhuǎn)發(fā)至下一跳,也就是 lvs 服務(wù)器。此時數(shù)據(jù)包源 IP 是 RIP,目的 IP 是 CIP。
⑥lvs 服務(wù)器收到 RS 響應(yīng)數(shù)據(jù)包后,根據(jù)路由查找,發(fā)現(xiàn)目的 IP 不是本機 IP,且 lvs 服務(wù)器開啟了轉(zhuǎn)發(fā)模式,所以將數(shù)據(jù)包轉(zhuǎn)發(fā)給 forward 鏈,此時數(shù)據(jù)包未作修改。
⑦lvs 收到響應(yīng)數(shù)據(jù)包后,根據(jù)目的 IP 和目的 port 查找服務(wù)和連接表,將源 IP 改為 VIP,通過路由查找,確定下一跳和出口信息,將數(shù)據(jù)包發(fā)送至網(wǎng)關(guān),經(jīng)過復(fù)雜的網(wǎng)絡(luò)到達用戶客戶端,最終完成了一次請求和響應(yīng)的交互。
NAT 模式雙向流量都經(jīng)過 LVS,因此 NAT 模式性能會存在一定的瓶頸。不過與其它模式區(qū)別的是,NAT 支持端口映射,且支持 windows 操作系統(tǒng)。
優(yōu)點、缺點與使用場景
NAT 模式優(yōu)點:
- 能夠支持 windows 操作系統(tǒng)。
- 支持端口映射。如果 rs 端口與 vport 不一致,lvs 除了修改目的 IP,也會修改 dport 以支持端口映射。
NAT 模式缺點:
- 后端 RS 需要配置網(wǎng)關(guān)
- 雙向流量對 lvs 負載壓力比較大
NAT 模式的使用場景:如果你是 windows 系統(tǒng),使用 lvs 的話,則必須選擇 NAT 模式了。
Tunnel 模式實現(xiàn)原理
Tunnel 模式在國內(nèi)使用的比較少,不過據(jù)說騰訊使用了大量的 Tunnel 模式。
它也是一種單臂的模式,只有請求數(shù)據(jù)會經(jīng)過 lvs,響應(yīng)數(shù)據(jù)直接從后端服務(wù)器發(fā)送給客戶端,性能也很強大,同時支持跨機房。
下邊繼續(xù)看圖分析原理:
實現(xiàn)原理與過程
①用戶請求數(shù)據(jù)包經(jīng)過多層網(wǎng)絡(luò),到達 lvs 網(wǎng)卡,此時數(shù)據(jù)包源 IP 是 cip,目的 ip 是 vip。
②經(jīng)過網(wǎng)卡進入網(wǎng)絡(luò)層 prerouting 位置,根據(jù)目的 ip 查找路由,確認是本機 ip,將數(shù)據(jù)包轉(zhuǎn)發(fā)到 input 鏈上,到達 lvs,此時源、目的 ip 都未發(fā)生變化。
③到達 lvs 后,通過目的 ip 和目的 port 查找是否為 IPVS 服務(wù)。
若是 IPVS 服務(wù),則會選擇一個 rs 作為后端服務(wù)器,以 rip 為目的 ip 查找路由信息,確定下一跳、dev 等信息,然后 IP 頭部前邊額外增加了一個 IP 頭(以 dip 為源,rip 為目的 ip),將數(shù)據(jù)包轉(zhuǎn)發(fā)至 output 上。
④數(shù)據(jù)包根據(jù)路由信息經(jīng)最終經(jīng)過 lvs 網(wǎng)卡,發(fā)送至路由器網(wǎng)關(guān),通過網(wǎng)絡(luò)到達后端服務(wù)器。
⑤后端服務(wù)器收到數(shù)據(jù)包后,ipip 模塊將 Tunnel 頭部卸載,正常看到的源 ip 是 cip,目的 ip 是 vip,由于在 tunl0 上配置 vip,路由查找后判定為本機 ip,送往應(yīng)用程序。
應(yīng)用程序 nginx 正常響應(yīng)數(shù)據(jù)后以 vip 為源 ip,cip 為目的 ip 數(shù)據(jù)包發(fā)送出網(wǎng)卡,最終到達客戶端。
Tunnel 模式具備 DR 模式的高性能,又支持跨機房訪問,聽起來比較完美。
不過國內(nèi)運營商有一定特色性,比如 RS 的響應(yīng)數(shù)據(jù)包的源 IP 為 VIP,VIP 與后端服務(wù)器有可能存在跨運營商的情況,很有可能被運營商的策略封掉。
Tunnel 在生產(chǎn)環(huán)境確實沒有使用過,在國內(nèi)推行 Tunnel 可能會有一定的難度吧。
優(yōu)點、缺點與使用場景
Tunnel 模式的優(yōu)點:
- 單臂模式,對 lvs 負載壓力小
- 對數(shù)據(jù)包修改較小,信息保存完整
- 可跨機房(不過在國內(nèi)實現(xiàn)有難度)
Tunnel 模式的缺點:
- 需要在后端服務(wù)器安裝配置 ipip 模塊
- 需要在后端服務(wù)器 tunl0 配置 vip
- 隧道頭部的加入可能導(dǎo)致分片,影響服務(wù)器性能
- 隧道頭部 IP 地址固定,后端服務(wù)器網(wǎng)卡 hash 可能不均
- 不支持端口映射
Tunnel 模式的使用場景:理論上,如果對轉(zhuǎn)發(fā)性能要求較高,且有跨機房需求,Tunnel 可能是較好的選擇。
到此為止,已經(jīng)將 LVS 原理講清楚了,內(nèi)容比較多,建議多看兩遍,由于文章篇幅太長,實踐操作的內(nèi)容就放到下篇文章再來講好了。
作者:肖邦
編輯:陶家龍
出處:轉(zhuǎn)載自公眾號編程修養(yǎng)(ID:chopin11vip)