在大規模互聯網應用中,負載均衡設備是必不可少的一個節點,源於互聯網應用的高並發和大流量的沖擊壓力,我們通常會在服務端部署多個無狀態的應用服務器和若干有狀態的存儲服務器(數據庫、緩存等等)。
一、負載均衡的作用
負載均衡設備的任務就是作為應用服務器流量的入口,首先挑選最合適的一台服務器,然后將客戶端的請求轉發給這台服務器處理,實現客戶端到真實服務端 的透明轉發。最近幾年很火的「雲計算」以及分布式架構,本質上也是將后端服務器作為計算資源、存儲資源,由某台管理服務器封裝成一個服務對外提供,客戶端 不需要關心真正提供服務的是哪台機器,在它看來,就好像它面對的是一台擁有近乎無限能力的服務器,而本質上,真正提供服務的,是后端的集群。
一個典型的互聯網應用的拓撲結構是這樣的:
二、負載均衡的類型
負載均衡可以采用硬件設備,也可以采用軟件負載。
商用硬件負載設備成本通常較高(一台幾十萬上百萬很正常),所以在條件允許的情況下我們會采用軟負載,軟負載解決的兩個核心問題是:選誰、轉發,其中最著名的是LVS(Linux Virtual Server)。
三、軟負載——LVS
LVS是四層負載均衡,也就是說建立在OSI模型的第四層——傳輸層之上,傳輸層上有我們熟悉的TCP/UDP,LVS支持TCP/UDP的負載均衡。
LVS的轉發主要通過修改IP地址(NAT模式,分為源地址修改SNAT和目標地址修改DNAT)、修改目標MAC(DR模式)來實現。
那么為什么LVS是在第四層做負載均衡?
首先LVS不像HAProxy等七層軟負載面向的是HTTP包,所以七層負載可以做的URL解析等工作,LVS無法完成。 其次,某次用戶訪問是與服務端建立連接后交換數據包實現的,如果在第三層網絡層做負載均衡,那么將失去「連接」的語義。軟負載面向的對象應該是一個已經建 立連接的用戶,而不是一個孤零零的IP包。后面會看到,實際上LVS的機器代替真實的服務器與用戶通過TCP三次握手建立了連接,所以LVS是需要關心 「連接」級別的狀態的。
LVS的工作模式主要有4種:
DR
NAT
TUNNEL
Full-NAT
這里挑選常用的DR、NAT、Full-NAT來簡單介紹一下。
1、DR
請求由LVS接受,由真實提供服務的服務器(RealServer, RS)直接返回給用戶,返回的時候不經過LVS。
DR模式下需要LVS和綁定同一個VIP(RS通過將VIP綁定在loopback實現)。
一個請求過來時,LVS只需要將網絡幀的MAC地址修改為某一台RS的MAC,該包就會被轉發到相應的RS處理,注意此時的源IP和目標IP都沒變,LVS只是做了一下移花接木。
RS收到LVS轉發來的包,鏈路層發現MAC是自己的,到上面的網絡層,發現IP也是自己的,於是這個包被合法地接受,RS感知不到前面有LVS的存在。
而當RS返回響應時,只要直接向源IP(即用戶的IP)返回即可,不再經過LVS。
DR模式是性能最好的一種模式。
2、NAT
NAT(Network Address Translation)是一種外網和內網地址映射的技術。
NAT模式下,網絡報的進出都要經過LVS的處理。LVS需要作為RS的網關。
當包到達LVS時,LVS做目標地址轉換(DNAT),將目標IP改為RS的IP。RS接收到包以后,仿佛是客戶端直接發給它的一樣。
RS處理完,返回響應時,源IP是RS IP,目標IP是客戶端的IP。
這時RS的包通過網關(LVS)中轉,LVS會做源地址轉換(SNAT),將包的源地址改為VIP,這樣,這個包對客戶端看起來就仿佛是LVS直接返回給它的。客戶端無法感知到后端RS的存在。
3、Full-NAT
無論是DR還是NAT模式,不可避免的都有一個問題:LVS和RS必須在同一個VLAN下,否則LVS無法作為RS的網關。
這引發的兩個問題是:
1、同一個VLAN的限制導致運維不方便,跨VLAN的RS無法接入。
2、LVS的水平擴展受到制約。當RS水平擴容時,總有一天其上的單點LVS會成為瓶頸。
Full-NAT由此而生,解決的是LVS和RS跨VLAN的問題,而跨VLAN問題解決后,LVS和RS不再存在VLAN上的從屬關系,可以做到多個LVS對應多個RS,解決水平擴容的問題。
Full-NAT相比NAT的主要改進是,在SNAT/DNAT的基礎上,加上另一種轉換,轉換過程如下:
在包從LVS轉到RS的過程中,源地址從客戶端IP被替換成了LVS的內網IP。
內網IP之間可以通過多個交換機跨VLAN通信。
當RS處理完接受到的包,返回時,會將這個包返回給LVS的內網IP,這一步也不受限於VLAN。
LVS收到包后,在NAT模式修改源地址的基礎上,再把RS發來的包中的目標地址從LVS內網IP改為客戶端的IP。
Full-NAT主要的思想是把網關和其下機器的通信,改為了普通的網絡通信,從而解決了跨VLAN的問題。采用這種方式,LVS和RS的部署在VLAN上將不再有任何限制,大大提高了運維部署的便利性。
4、Session
客戶端與服務端的通信,一次請求可能包含多個TCP包,LVS必須保證同一連接的TCP包,必須被轉發到同一台RS,否則就亂套了。為了確保這一點,LVS內部維護着一個Session的Hash表,通過客戶端的某些信息可以找到應該轉發到哪一台RS上。
5、LVS集群化
采用Full-NAT模式后,可以搭建LVS的集群,拓撲結構如下圖:
6、容災
容災分為RS的容災和LVS的容災。
RS的容災可以通過LVS定期健康檢測實現,如果某台RS失去心跳,則認為其已經下線,不會在轉發到該RS上。
LVS的容災可以通過主備+心跳的方式實現。主LVS失去心跳后,備LVS可以作為熱備立即替換。
容災主要是靠KeepAlived來做的。