LVS是構(gòu)建在real server集群之上的、具有高擴展性和可用性的虛擬服務器,通常我們稱之為“負載均衡”服務器。服務器的集群架構(gòu)對用戶而言是透明度,用戶與集群系統(tǒng)交互時,就像與單個高性能的虛擬服務器交互一樣;這對構(gòu)架較大規(guī)模的服務站點,有極大的幫助。
實際服務器(real servers)和負載均衡服務器(LVS等)通過高速的LAN或者在地理位置上分散的WAN互相鏈接。負載均衡器將請求分發(fā)給不同的server,讓多個server并行的服務,看起來像是一個IP上的虛擬服務;請求分發(fā)時可以使用基于IP的負載均衡技術(shù),或者使用應用層面的負載均衡技術(shù)(TCP,HTTP)。系統(tǒng)的擴展,可以通過在集群中增、刪節(jié)點(real server)來實現(xiàn),這都是透明的;它提供了節(jié)點活性檢測機制、守護進程失效檢測,并適當重新配置系統(tǒng)。
一、為什么使用LVS
隨著互聯(lián)網(wǎng)的高速增長,那么互聯(lián)網(wǎng)的流量也急劇增加,server的負載也隨之加重,特別是一些比較流行的web站點,它很容易就不堪負重。為了解決服務器的過載問題,有2種方案。一個是單server方案,即升級server的物理配置以提供更高的性能,但是當請求量不斷增加,又要面臨繼續(xù)升級的問題,升級硬件的過程比較復雜(需要停機)而且成本較高,終歸單個server的升級是有瓶頸的,我們不能一直這樣下去;另個方案就是多server復合使用,即我們常說的集群架構(gòu),我們使用多個廉價的server構(gòu)建一個集群,讓它們并行提供服務,當web站點的負載增加,我們只需要簡單的增加一個或者多個server即可,性價比很高,所以在構(gòu)架大型分布式服務時,這種方案更具有擴展性。
有如下幾種方式來構(gòu)建分布式服務器:
1)基于DNS的負載均衡集群
這種方式是構(gòu)建分布式網(wǎng)絡(luò)最簡單的方式。DNS系統(tǒng)可以將一個域名解析到多個不同的IP地址上,當DNS服務器收到域名解析請求時(比如客戶端本地沒有域名的解析信息),DNS服務器將根據(jù)調(diào)度算法(比如輪詢)選擇一個IP返回給請求端,由本地DNS將此解析信息緩存一定的時間(TTL),此后客戶端對此域名的請求將會使用此IP作為目標地址。
可是,因為客戶端的cache和層級的DNS系統(tǒng)(即不同層級的DNS可能緩存的IP不同或相同,參見DNS相關(guān)文檔),很容易導致server之間的負載不均衡,不能實現(xiàn)動態(tài)負載均衡,而且不容易處理峰值負載。在DNS服務器上,選擇合適的TTL值也很困難,值太小將會增加DNS的流量和負載,DNS服務器會成為瓶頸,較大的值將會使用動態(tài)均衡性變得更差。即使TTL設(shè)置為0,調(diào)度的粒度也因host不同,不同的用戶訪問模式也會導致負載不平衡,因為有些用戶可能訪問大量的站點內(nèi)容,有些用戶可能只訪問較少的頁面。重要的是,它也不可靠,當服務器失效(宕機),那么映射到此Server IP上的客戶端將不能訪問(最長TTL時間內(nèi)),即使他們在瀏覽上使用“refresh”、“reload”操作。
2)基于負載均衡集群的分發(fā)器
Dispatcher(分發(fā)器),即負載均衡器,可以將請求分發(fā)給集群中不同的server,所以集群中并行的服務,對客戶端而言,看起來像是運行在一個IP上的虛擬服務,終端用戶只需要與單個server交互而不需要知道整個集群的所有Servers。和DNS負載均衡相比,Dispatcher能夠細顆粒度的調(diào)度請求,比如根據(jù)connection,更好在servers之間實現(xiàn)負載均衡。當real server失效時它被標記為“失效”,server管理也非常簡單,管理員可以在任何時候增、減server,而不需要打斷終端用戶對服務的使用。
負載均衡可以在2個層面來做:應用層(Application-Level)和IP層(IP-Level)。比如“Reverse-Proxy”和“pWEB”是應用層的負載均衡器,用來構(gòu)架擴展性的web服務器集群,它們將HTTP請求轉(zhuǎn)發(fā)給集群中不同的web服務器,獲取響應,并返回給客戶端;因為在應用層,HTTP請求的處理和應答是高耗的,那么當集群中服務器的數(shù)量增加到5個或者更多,這種應用層負載均衡器也會成為瓶頸,這依賴于每個server的吞吐能力。
我們更傾向于IP層的負載均衡,因為它的性能消耗較小,可以承載多達25甚至100個server的負載均衡。這也是IP虛擬服務器的設(shè)計目的。LVS的核心就是IP層的負載均衡。
二、虛擬服務器是如何運作的?
目前為止,虛擬服務器(Virtual Server)有三種實現(xiàn)方式,這三種IP負載均衡技術(shù)同時存在于LinuxDirector中:NAT,IP Tunneling,Direct routing。下文中“虛擬服務器”為“Virtual Server”(LVS),負載均衡器為“l(fā)oad balancer”,虛擬服務器具有“負載均衡器”組件。
1、NAT
NAT的優(yōu)點是real server可以使用任何操作系統(tǒng)(linux,Mac OS,windows等),只要它能夠支持TCP/IP協(xié)議即可,real servers能夠使用私有網(wǎng)絡(luò)地址(private網(wǎng)絡(luò)),只需要給負載均衡server一個外網(wǎng)IP即可。
缺點是,NAT模式下,虛擬服務器的擴展能力有限,當集群中server的數(shù)量增長到20或者更多時,負載均衡器將成為整個系統(tǒng)的瓶頸,因為請求數(shù)據(jù)包和響應數(shù)據(jù)包都需要通過負載均衡器的重寫(rewritten)。假設(shè),TCP的數(shù)據(jù)包的大小為536字節(jié),重寫數(shù)據(jù)包耗時60us(微秒,百萬分之一秒),負載均衡器最大的吞吐量為8.93M/s,如果real server的吞吐能力為400KB/s,那么負載均衡器能夠調(diào)度22個real server。
通過NAT實現(xiàn)的虛擬服務器能夠滿足大量客戶端的請求;當負載均衡器成為整個系統(tǒng)的瓶頸時,有2種途徑可以解決這個問題。一個是混合途徑(hybrid),另一種則是使用IP tunneling或者Direct routing。在DNS混合途徑中,有多個基于NAT的集群環(huán)境,域名映射到多個虛擬服務器的IP。我們可以使用LVS中的“IP Tunneling”、“Direct Routing”提高擴展性,也可以在第一級使用“IP Tunneling”或者“Direct Routing”負載均衡器,然后在第二級使用NAT模式,以構(gòu)建大規(guī)模的集群。(LVS DR + nginx就是這種模式)
NAT模式,這和nginx的負載均衡模式非常相似。
2、IP Tunneling
我們已經(jīng)了解到,NAT模式弊端在于請求和響應都需要經(jīng)過負載均衡器,這限制了集群的規(guī)模的擴展。對于大多數(shù)web應用,請求的數(shù)據(jù)包較小,響應的數(shù)據(jù)包較大。
IP Tunneling模式的虛擬服務器,負載均衡器只需要將請求分發(fā)給不同的real server,real server直接將響應返回給客戶端。所以,負載均衡器能夠處理海量的請求,它能夠調(diào)度高達100個real server,并且它不會成為系統(tǒng)的瓶頸。Tunneling的吞吐能力高達1GB,而負載均衡器只有100M的全雙工網(wǎng)絡(luò)適配器。
由此可見,IP Tunneling特性可以用來構(gòu)建性能極高的虛擬服務器,非常適合構(gòu)建虛擬代理服務器,因為當代理服務器收到請求后,它可以直接訪問網(wǎng)絡(luò),獲取內(nèi)容,并直接返回給用戶。
不過,所有的server需要支持“IP Tunneling”協(xié)議(即IP封裝,IPIP),目前已知的只有l(wèi)inux系統(tǒng)均支持此特性。
3、Direct Routing
像“IP Tunneling”一樣,linuxDirector處理的只是Client-Server的半鏈接,響應數(shù)據(jù)可以根據(jù)各自的網(wǎng)絡(luò)路由方式到達客戶端,即負載均衡器接收請求,請求轉(zhuǎn)發(fā)給real server,然后響應直接返回給客戶端而無需經(jīng)過負載均衡器。它具有“IP Tunneling”的優(yōu)點。
不過和“IP Tunneling”相比,這種方式并沒有“tunneling”的開支(IP封裝,其實開支非常小),但是它需要負載均衡器網(wǎng)絡(luò)接口與real server的網(wǎng)絡(luò)接口必須在同一個物理網(wǎng)段。
根據(jù)上述介紹,我們簡單的得到結(jié)論:“IP Tunneling”和“Direct Routing”模式能夠構(gòu)建較大規(guī)模的集群負載,擴展性比NAT更強;“NAT”網(wǎng)絡(luò)拓撲結(jié)構(gòu)簡單,real server只需要支持TCP/IP協(xié)議即可,它們可以在LAN、WAN網(wǎng)絡(luò)中;“IP Tunneling”需要集群中的real server支持IP封裝協(xié)議,real server可以位于LAN、WAN網(wǎng)絡(luò)中,在實際環(huán)境中,配置稍微復雜,這種模式不常用;“Direct Routing”模式需要LVS與real server位于同一網(wǎng)段,配置簡單,是比較常用的方式。
三、LVS集群架構(gòu)
為了整個系統(tǒng)的透明度、可擴展性、可用性以及可管理性,我們通常采用如圖所示的三層架構(gòu):
三層架構(gòu)有如下幾個部分組成:
1、load balancer(負載均衡器):位于整個集群的前端,用于在多個real server之間均衡來自客戶端的請求 ,對于客戶端而言它們認為所有的服務均來自一個IP地址,即load blancer的IP地址。
2、server cluster(服務器集群):有多個real server組成,它們提供同等的服務。
3、shared storage(共享存儲):用于提供servers共享的存儲空間,這是servers獲取相同的內(nèi)容、提供相同的服務的基礎(chǔ)。
負載均衡器是整個集群系統(tǒng)的單一入口,它可以運行IPVS(linux內(nèi)核中)以提供基于IP的負載均衡技術(shù),或者是運行KTCPVS來實現(xiàn)應用層的負載均衡。當使用IPVS時,所有的servers需要提供相同的服務和內(nèi)容,負載均衡器通過指定的調(diào)度算法和server都負載情況,將客戶端請求轉(zhuǎn)發(fā)給某個合適的server。無論選擇了哪個server,最終的響應結(jié)果應該是一樣的(否則就違背了集群服務的基本原則)。當使用KTCPVS時,servers可以返回不同的內(nèi)容,負載均衡器可以根據(jù)請求的內(nèi)容(URL,參數(shù)等)將請求轉(zhuǎn)發(fā)給不同的server。因為KTCPVS是linux內(nèi)核實現(xiàn),所以處理數(shù)據(jù)的開支較小,整個集群仍然能夠提供較高的吞吐量。
集群中server節(jié)點的數(shù)量可以根據(jù)系統(tǒng)的負載而調(diào)整,當所有的server都過載時,我們需要向集群增加多個新的servers來處理這些增長的工作量。對于大多數(shù)互聯(lián)網(wǎng)服務,比如web站點,請求之間相關(guān)性不高,它們可以在不同的server上并行運行,因此,隨著集群中server數(shù)量的增加,整個系統(tǒng)的性能也會成線性擴展。
共享存儲,可以是數(shù)據(jù)庫系統(tǒng)、網(wǎng)絡(luò)文件系統(tǒng)(NFS),或者是分布式文件系統(tǒng)(DFS);需要server節(jié)點動態(tài)更新的數(shù)據(jù)需要被保存在數(shù)據(jù)庫中,當多個server節(jié)點并行讀寫數(shù)據(jù)庫系統(tǒng)時,數(shù)據(jù)庫需要保證數(shù)據(jù)的一致性(并發(fā)操作);對于靜態(tài)數(shù)據(jù),通??梢员4嬖谖募到y(tǒng)中,比如NFS,這些數(shù)據(jù)可以被所有的server節(jié)點共享。但是單個NFS系統(tǒng)擴展性是有限制的,一個NFS只能支撐4~8個server節(jié)點的訪問;對于更大規(guī)模的系統(tǒng),通常使用分布式文件系統(tǒng),比如GFS,這樣共享存儲系統(tǒng)可以根據(jù)需要進行規(guī)模擴展。
負載均衡器、服務器集群、共享存儲系統(tǒng),這三者之間通常使用高速的網(wǎng)絡(luò)鏈接,比如100M和GB以太網(wǎng)網(wǎng)絡(luò),所以當系統(tǒng)不斷增長時網(wǎng)絡(luò)不會成為它們之間的瓶頸。
四、高可用性
越來越多的重要應用遷移到互聯(lián)網(wǎng)上,那么提供高可用的服務將變得非常重要。集群系統(tǒng)的優(yōu)勢之一就是軟硬件的冗余性,因為集群系統(tǒng)有多個獨立的節(jié)點構(gòu)成,并且每個節(jié)點都運行相同的應用系統(tǒng),高可用性可以通過移除失效節(jié)點和適當重新配置集群系統(tǒng)的手段實現(xiàn),集群中剩余的節(jié)點即可接管失效節(jié)點上的工作量。
其實“高可用性”是一個較大的領(lǐng)域,一個先進的高可用系統(tǒng)會包含可靠的“組通訊子系統(tǒng)”、“成員管理”、“quoram子系統(tǒng)”、“并發(fā)控制子系統(tǒng)”等等。其中必有很多事情需要解決,不過,我們可以使用現(xiàn)有的軟件包來構(gòu)建高可用的LVS集群系統(tǒng)。
工作原理:
通常情況下,負載均衡器會運行一個監(jiān)控服務來間歇性的檢測server的健康狀況,如下圖所示。如果對server的服務訪問請求或者ICMP(ping)沒有收到響應,那么服務監(jiān)控(monitor)將會認為此server已經(jīng)“dead”,并從可用server列表中移除,此后將不會有請求被轉(zhuǎn)發(fā)到此server上。當monitor檢測到失效的server恢復正常,那么將此server重新添加到可用server列表中,因此負載均衡器可以自動標記失效的server。當然,管理員也可以使用系統(tǒng)工具來增減server,以維護集群系統(tǒng),而無需關(guān)閉整個集群服務。
不過負載均衡器或許成為整個系統(tǒng)的單點問題,為了避免因為負載均衡器的失效而導致整個集群服務不可用,我們需要對負載均衡器增加backup(一個或多個)。兩個heartbeat守護進程分別運行在primary和backup節(jié)點,它們間歇性的互相發(fā)送心跳消息,如果backup的心跳進程在一段時間內(nèi)無法收到來自(發(fā)送)primary節(jié)點的心跳消息,它將接管提供負載均衡服務的VIP地址;當那個失效的負載均衡器恢復工作,此時會有2種情況,一是它成為backup,另一種情況則是當前active的負載均衡器釋放VIP,它接管VIP并繼續(xù)成為primary。
primary負載均衡器持有鏈接的狀態(tài),即客戶端鏈接被轉(zhuǎn)發(fā)到哪個server上,如果backup接管VIP后,其上沒有這些鏈接狀態(tài)的信息,客戶端需要重新請求。為了讓負載均衡器的故障轉(zhuǎn)移對客戶端應用透明,我們在IPVS中實現(xiàn)了鏈接同步,primary IPVS將會把鏈接狀態(tài)信息通過UDP多播方式同步給backup。當backup負載均衡器接管后,其上已經(jīng)持有了絕大多數(shù)鏈接狀態(tài)信息,所以幾乎所有的鏈接將可以繼續(xù)通過backup負載均衡器訪問服務。(備注:請參看keepalived相關(guān)技術(shù)文檔)
五、NAT模式
歸因于IPv4地址的短缺或者一些安全原因,越來越多的網(wǎng)絡(luò)使用一些局域網(wǎng)地址(比如,以“10”、“198”、“172”開頭的IP地址)這些地址無法在互聯(lián)網(wǎng)上使用。如果這些內(nèi)部網(wǎng)絡(luò)地址需要訪問互聯(lián)網(wǎng),或者被互聯(lián)網(wǎng)訪問,則需要網(wǎng)絡(luò)地址轉(zhuǎn)換(發(fā)生在路由器上)。(即NAT模式下,只需要負載均衡器有實際外網(wǎng)IP即可,同時需要一個外網(wǎng)的VIP,對于real server則使用內(nèi)網(wǎng)IP)
網(wǎng)絡(luò)地址轉(zhuǎn)換是將一組IP地址映射到另一組上。當?shù)刂酚成涫荖到N,(即一對一),我們成為靜態(tài)網(wǎng)絡(luò)地址轉(zhuǎn)換;如果是M到N(M > N),這種情況稱之為動態(tài)網(wǎng)絡(luò)地址轉(zhuǎn)換。其中N-1的這種mapping,使用linux IP偽裝實現(xiàn)。
當用戶訪問集群服務時,請求數(shù)據(jù)包發(fā)往VIP地址(負載均衡器的地址)的負載均衡器,負載均衡器檢測數(shù)據(jù)包的地址和端口號,根據(jù)虛擬服務器規(guī)則表,如果它們與虛擬服務器上的服務匹配(配置文件決定),那么將會根據(jù)調(diào)度算法從集群中選擇一個real server,此鏈接將會被添加到一個hashtable上,此hashtable記錄了那些已經(jīng)建立的鏈接。然后數(shù)據(jù)包的目標地址和端口將會被重寫為當前選擇的real server,并且數(shù)據(jù)包將會由負載均衡器轉(zhuǎn)給被選擇的real server。此后,來自此鏈接的數(shù)據(jù)包(package)且被選擇的real server能夠在hashtable中找到,那么數(shù)據(jù)包將繼續(xù)被重寫并轉(zhuǎn)發(fā)到此real server上。當應答的數(shù)據(jù)包返回時,負載均衡器將數(shù)據(jù)包中的源地址和端口重寫為虛擬服務的地址和端口(LVS)并返回給客戶端。當鏈接中斷或者超時,鏈接記錄將會從hashtable中刪除。
或許比較迷惑,那么我們看圖所示。
real server可以運行任何任何OS,只需要支持TCP/UDP即可,real servers的默認路徑必須時虛擬服務器(172.16.0.1),ipwadm工具可以讓虛擬server接收來自real server的數(shù)據(jù)包。
所有訪問的目標地址為“202.103.106.5”端口為80的流量都會被負載均衡器轉(zhuǎn)發(fā)給“172.16.0.2:80”和“172.16.0.3:8000”。數(shù)據(jù)包重寫的方式如下所示:
Java代碼
#請求web服務的數(shù)據(jù)包包含源地址和目標地址,其中源地址為客戶端地址,目標地址為負載均衡器的VIP地址
SOURCE 202.100.1.2:3456 DEST 202.103.106.5:80
#負載軍很輕將會選擇一個real server,比如172.16.0.3:8000,數(shù)據(jù)包將會被重寫并轉(zhuǎn)發(fā)到此server:
SOURCE 202.100.1.2.3456 DEST 172.16.0.3:8000
#響應的數(shù)據(jù)包到達負載均衡器
SOURCE 172.16.0.3:8000 DEST 202.100.1.2:3456
#負載均衡器將會重寫響應包,并返回給客戶端
SOURCE 202.103.106.5:80 DEST 202.100.1.2:3456
關(guān)于NAT模式的LVS配置,請參見官網(wǎng)。
六、IP Tunneling模式
對于小型的負載均衡架構(gòu),我們采用NAT模式即可滿足設(shè)計要求。那么當集群擴展到足夠大時,NAT模式下負載均衡器將成為瓶頸,最大的原因就是響應的數(shù)據(jù)也必須有負載均衡器重寫后轉(zhuǎn)發(fā)給客戶端。IP Tunneling能夠規(guī)避這個問題。
IP Tunneling即IP封裝(IPIP協(xié)議),它將IP報文重新封裝成另一個IP報文的技術(shù),這就允許將發(fā)往一個IP地址的報文數(shù)據(jù)重新包裝并重定向到另一個IP地址。IP封裝技術(shù)目前常用在“Extranet”(外聯(lián)網(wǎng))、Mobile-IP、IP-Multicast等。具體請參見相關(guān)文檔。
它和NAT模式最大的不同就是負載均衡器通過IP Tunneling方式將請求發(fā)送給real server。
到達負載均衡器的請求數(shù)據(jù)包,將會進行IP封裝并轉(zhuǎn)發(fā)給real server,當server收到數(shù)據(jù)包后將會解包并處理請求,最終將響應數(shù)據(jù)根據(jù)自己的路由直接返回給客戶端。
需要注意的時,real server可以使用任何實際的IP地址,它們可以是地址位置分散的,但是它們必須支持IP封裝協(xié)議。它們的“tunnel”設(shè)備需要配置起來,使得系統(tǒng)能夠正確的解包,同時VIP地址必須配置在非ARP設(shè)備上(non-arp),或者系統(tǒng)配置為可以將VIP上的數(shù)據(jù)包重定向本地socket。
最終,當一個封裝的數(shù)據(jù)包到達real server,real server解包,發(fā)現(xiàn)此包的目標地址為VIP,那么它將處理此請求(因為VIP地址已經(jīng)在tunel網(wǎng)卡接口上配置了),此后將響應結(jié)果直接返回給用戶終端。其中最重要的一步就是將所有的real server的“tunnel”網(wǎng)絡(luò)接口增加VIP地址的配置。比如負載均衡器的VIP地址為“202.103.106.5”,那么在real server的“tunnel”網(wǎng)卡需要增加此VIP,否則數(shù)據(jù)包將被丟棄。
七、Direct Routing
real server和負載均衡器共享VIP地址(同IP Tunneling),負載均衡器也需要在一個網(wǎng)卡接口上配置VIP地址,用來接受請求,它直接將請求數(shù)據(jù)轉(zhuǎn)發(fā)給選擇的real server,所有的real server需要在它們的非ARP網(wǎng)絡(luò)接口(non-arp)配置VIP地址,將來自VIP的數(shù)據(jù)包直接轉(zhuǎn)到給本地socket,所以real server可以在本地處理這些請求。負載均衡器和real servers的網(wǎng)絡(luò)接口中必須有一個通過HUB/Switch物理相連。架構(gòu)圖示如下:
當用戶通過LVS訪問集群服務時,數(shù)據(jù)包被發(fā)往VIP,負載均衡器將會選擇一個real server,并將請求轉(zhuǎn)發(fā)給它,real server接收到請求數(shù)據(jù)后,發(fā)現(xiàn)數(shù)據(jù)包的目標地址在自己的網(wǎng)絡(luò)接口上,所以它將繼續(xù)處理請求,并直接將響應結(jié)果返回給終端用戶。
負載均衡器只是簡單的將數(shù)據(jù)幀的目標MAC地址修改為real server的mac地址,并在LAN上重新發(fā)送(路由器),這也是負載均衡器和real server必須通過單個不間斷的LAN網(wǎng)段直接相連的原因。(即負載均衡器需要與real server在一個LAN網(wǎng)段中,且它們在在一個網(wǎng)卡上配置VIP)。
關(guān)于LVS的相關(guān)配置與安裝,請參見其他文檔。
八、調(diào)度算法
LVS中負載均衡器共有10中算法,其中五種比較常用:
1)輪詢(Round Robin):將請求有序的分發(fā)給不同的real server,這是一種比較公平的算法。
2)加權(quán)輪詢(Weighted Round-Robin):根據(jù)real server的實際處理能力不同,而設(shè)定不同的權(quán)重,在請求分發(fā)時采用輪詢,權(quán)重越高的server將獲得更多的請求。
3)最小鏈接數(shù)(Least Connections):將請求分發(fā)給鏈接數(shù)最少的real server。這是動態(tài)負載均衡比較常用的算法。
4)加權(quán)最小鏈接數(shù):
5)源地址散列(Source Hashing):根據(jù)請求的源IP地址作為hash key,real servers作為散列表。