LVS三種負載均衡方式(VS/NAT、VS/TUN、VS/DR)和 調度算法介紹

LVS

LVS是一種集羣(Cluster)技術,採用IP負載均衡技術和基於內容請求分發技術。調度器具有很好的吞吐率,將請求均衡地轉移到不同的服務器上執行,且調度器自動屏蔽掉服務器的故障,從而將一組服務器構成一個高性能的、高可用的虛擬服務器。整個服務器集羣的結構對客戶是透明的,而且無需修改客戶端和服務器端的程序。

一、LVS主要組成部分

  負載調度器(load balancer/ Director),它是整個集羣對外面的前端機,負責將客戶的請求發送到一組服務器上執行,而客戶認爲服務是來自一個IP地址(我們可稱之爲虛擬IP地址)上的。

  服務器池(server pool/ Realserver),是一組真正執行客戶請求的服務器,執行的服務一般有WEB、MAIL、FTP和DNS等。

  共享存儲(shared storage),它爲服務器池提供一個共享的存儲區,這樣很容易使得服務器池擁有相同的內容,提供相同的服務。

二、LVS負載均衡方式:

(1) Virtual Server via Network Address Translation NAT(VS/NAT)

  VS/NAT是一種最簡單的方式,所有的RealServer只需要將自己的網關指向Director即可。客戶端可以是任意操作系統,但此方式下,一個Director能夠帶動的RealServer比較有限。在VS/NAT的方式下,Director也可以兼爲一臺RealServer。VS/NAT的體系結構如圖所示。

(2) Virtual Server via IP Tunneling(VS/TUN)

  IP隧道(IP tunneling)是將一個IP報文封裝在另一個IP報文的技術,這可以使得目標爲一個IP地址的數據報文能被封裝和轉發到另一個IP地址。IP隧道技術亦稱爲IP封裝技術(IP encapsulation)。IP隧道主要用於移動主機和虛擬私有網絡(Virtual Private Network),在其中隧道都是靜態建立的,隧道一端有一個IP地址,另一端也有唯一的IP地址。它的連接調度和管理與VS/NAT中的一樣,只是它的報文轉發方法不同。調度器根據各個服務器的負載情況,動態地選擇一臺服務器,將請求報文封裝在另一個IP報文中,再將封裝後的IP報文轉發給選出的服務器;服務器收到報文後,先將報文解封獲得原來目標地址爲 VIP 的報文,服務器發現VIP地址被配置在本地的IP隧道設備上,所以就處理這個請求,然後根據路由表將響應報文直接返回給客戶。

(3) Virtual Server via Direct Routing(VS/DR)

  VS/DR方式是通過改寫請求報文中的MAC地址部分來實現的。Director和RealServer必需在物理上有一個網卡通過不間斷的局域網相連。 RealServer上綁定的VIP配置在各自Non-ARP的網絡設備上(如lo或tunl),Director的VIP地址對外可見,而RealServer的VIP對外是不可見的。RealServer的地址即可以是內部地址,也可以是真實地址。

VS/DR的工作流程如圖所示:它的連接調度和管理與VS/NAT和VS/TUN中的一樣,它的報文轉發方法又有不同,將報文直接路由給目標服務器。在VS/DR中,調度器根據各個服務器的負載情況,動態地選擇一臺服務器,不修改也不封裝IP報文,而是將數據幀的MAC地址改爲選出服務器的MAC地址,再將修改後的數據幀在與服務器組的局域網上發送。因爲數據幀的MAC地址是選出的服務器,所以服務器肯定可以收到這個數據幀,從中可以獲得該IP報文。當服務器發現報文的目標地址VIP是在本地的網絡設備上,服務器處理這個報文,然後根據路由表將響應報文直接返回給客戶。

  VS/DR的方式是目前大型網站使用最廣泛的一種負載均衡手段。

三、三種LVS負載均衡技術的優缺點歸納表:

LVS 常用的調度算法:

固定調度算法:rr,wrr,dh,sh

靜態方法僅根據算法本身進行調度,關心的是起點公平。相對LVS而言的,而不關心RS是否可以處理請求,如RS的負載狀態。

有如下4類算法

RRroundrobin

輪詢,後端RS均攤所有的請求

WRRWeighted RR

加權輪詢,根據權值來分配請求的數量

SHSource Hashing

源地址hash,實現session sticky,源IP地址hash;將來自於同一個IP地址的請求始終發往第一次挑中的RS,從而實現會話綁定

但是,這種方式問題比較多,如源地址是nat後的公網地址,如果該地址對應的後端機器很多,這樣同一ip的訪問可能會對同一服務器造成負擔。

DHDestination Hashing

目標地址哈希,將發往同一個目標地址的請求始終轉發至第一次挑中的RS,典型使用場景是正向代理緩存場景中的負載均衡,如:寬帶運營商

 

 

動態調度算法:wlc,lc,lblc,lblcr

 

動態主要根據每RS當前的負載狀態及調度算法進行調度Overhead=value較小的RS將被調度

動態調度關心的是最終的結果,要考慮到後端服務器RS的負載情況

有如下6類算法

LCleast connections

適用於長連接應用

Overhead=activeconns*256+inactiveconns

活動連接表示正在傳送數據

非活動連接表示建立連接了,但是沒有傳送數據

WLCWeighted LC

WLC是默認調度方法

Overhead=(activeconns*256+inactiveconns)/weight

這裏如果是第一次連接,活動和非活動連接的值都是0.,這樣同LC和WL的算法計算結果都是0,需要通過SED來解決這個問題。因爲初始+1,就會有數值的對比

SEDShortest Expection Delay

初始連接高權重優先,Overhead=(activeconns+1)*256/weight

NQNever Queue

第一輪均勻分配,後續SED,解決了第一次分配不均勻的問題。使得所有的服務器都會執行一定的任務

LBLCLocality-Based LC

動態的DH算法,使用場景:根據負載狀態實現正向代理

LBLCRLBLC with Replication

帶複製功能的LBLC,解決LBLC負載不均衡問題,從負載重的複製到負載輕的RS

 

 

輪叫調度(Round-Robin Scheduling)

 

輪叫調度(Round Robin Scheduling)算法就是以輪叫的方式依次將請求調度不同的服務器,即每次調度執行i = (i + 1) mod n,並選出第i臺服務器。算法的優點是其簡潔性,它無需記錄當前所有連接的狀態,所以它是一種無狀態調度。

在系統實現時,我們引入了一個額外條件,當服務器的權值爲零時,表示該服務器不可用而不被調度。這樣做的目的是將服務器切出服務(如屏蔽服務器故障和系統維護),同時與其他加權算法保持一致。所以,算法要作相應的改動,它的算法流程如下:

輪叫調度算法流程

假設有一組服務器S = {S0, S1, …, Sn-1},一個指示變量i表示上一次選擇的

服務器,W(Si)表示服務器Si的權值。變量i被初始化爲n-1,其中n > 0。

j = i;

do {

j = (j + 1) mod n;

if (W(Sj) > 0) {

i = j;

return Si;

}

} while (j != i);

return NULL;

輪叫調度算法假設所有服務器處理性能均相同,不管服務器的當前連接數和響應速度。該算法相對簡單,不適用於服務器組中處理性能不一的情況,而且當請求服務時間變化比較大時,輪叫調度算法容易導致服務器間的負載不平衡。

雖然Round-Robin DNS方法也是以輪叫調度的方式將一個域名解析到多個IP地址,但輪叫DNS方法的調度粒度是基於每個域名服務器的,域名服務器對域名解析的緩存會妨礙輪叫解析域名生效,這會導致服務器間負載的嚴重不平衡。這裏,IPVS輪叫調度算法的粒度是基於每個連接的,同一用戶的不同連接都會被調度到不同的服務器上,所以這種細粒度的輪叫調度要比DNS的輪叫調度優越很多。

 

加權輪叫調度(Weighted Round-Robin Scheduling)

輪叫調度(Round Robin Scheduling)算法就是以輪叫的方式依次將請求調度不同的服務器,即每次調度執行i = (i + 1) mod n,並選出第i臺服務器。算法的優點是其簡潔性,它無需記錄當前所有連接的狀態,所以它是一種無狀態調度。

在系統實現時,我們引入了一個額外條件,當服務器的權值爲零時,表示該服務器不可用而不被調度。這樣做的目的是將服務器切出服務(如屏蔽服務器故障和系統維護),同時與其他加權算法保持一致。所以,算法要作相應的改動,它的算法流程如下:

加權輪叫調度算法流程

假設有一組服務器S = {S0, S1, …, Sn-1},W(Si)表示服務器Si的權值,一個

指示變量i表示上一次選擇的服務器,指示變量cw表示當前調度的權值,max(S)

表示集合S中所有服務器的最大權值,gcd(S)表示集合S中所有服務器權值的最大

公約數。變量i初始化爲-1,cw初始化爲零。

while (true) {

  i = (i + 1) mod n;

  if (i == 0) {

    cw = cw - gcd(S);

    if (cw <= 0) {

      cw = max(S);

      if (cw == 0)

        return NULL;

    }

  }

  if (W(Si) >= cw)

    return Si;

}

輪叫調度算法假設所有服務器處理性能均相同,不管服務器的當前連接數和響應速度。該算法相對簡單,不適用於服務器組中處理性能不一的情況,而且當請求服務時間變化比較大時,輪叫調度算法容易導致服務器間的負載不平衡。

雖然Round-Robin DNS方法也是以輪叫調度的方式將一個域名解析到多個IP地址,但輪叫DNS方法的調度粒度是基於每個域名服務器的,域名服務器對域名解析的緩存會妨礙輪叫解析域名生效,這會導致服務器間負載的嚴重不平衡。這裏,IPVS輪叫調度算法的粒度是基於每個連接的,同一用戶的不同連接都會被調度到不同的服務器上,所以這種細粒度的輪叫調度要比DNS的輪叫調度優越很多。

 

最小連接調度(Least-Connection Scheduling)

最小連接調度(Least-Connection Scheduling)算法是把新的連接請求分配到當前連接數最小的服務器。最小連接調度是一種動態調度算法,它通過服務器當前所活躍的連接數來估計服務器的負載情況。調度器需要記錄各個服務器已建立連接的數目,當一個請求被調度到某臺服務器,其連接數加1;當連接中止或超時,其連接數減一。

在系統實現時,我們也引入當服務器的權值爲零時,表示該服務器不可用而不被調度,它的算法流程如下:

最小連接調度算法流程

假設有一組服務器S = {S0, S1, ..., Sn-1},W(Si)表示服務器Si的權值,

C(Si)表示服務器Si的當前連接數。

for (m = 0; m < n; m++) {

if (W(Sm) > 0) {

for (i = m+1; i < n; i++) {

if (W(Si) <= 0)

continue;

if (C(Si) < C(Sm))

m = i;

}

return Sm;

}

}

return NULL;

當各個服務器有相同的處理性能時,最小連接調度算法能把負載變化大的請求分佈平滑到各個服務器上,所有處理時間比較長的請求不可能被髮送到同一臺服務器上。但是,當各個服務器的處理能力不同時,該算法並不理想,因爲TCP連接處理請求後會進入TIME_WAIT狀態,TCP的TIME_WAIT一般爲2分鐘,此時連接還佔用服務器的資源,所以會出現這樣情形,性能高的服務器已處理所收到的連接,連接處於TIME_WAIT狀態,而性能低的服務器已經忙於處理所收到的連接,還不斷地收到新的連接請求。

加權最小連接調度(Weighted Least-Connection Scheduling)

加權最小連接調度(Weighted Least-Connection Scheduling)算法是最小連接調度的超集,各個服務器用相應的權值表示其處理性能。服務器的缺省權值爲1,系統管理員可以動態地設置服務器的權值。加權最小連接調度在調度新連接時儘可能使服務器的已建立連接數和其權值成比例。加權最小連接調度的算法流程如下:

加權最小連接調度的算法流程

假設有一組服務器S = {S0, S1, ..., Sn-1},W(Si)表示服務器Si的權值,

C(Si)表示服務器Si的當前連接數。所有服務器當前連接數的總和爲

CSUM = ΣC(Si)  (i=0, 1, .. , n-1)。當前的新連接請求會被髮送服務器Sm,

當且僅當服務器Sm滿足以下條件

  (C(Sm) / CSUM)/ W(Sm) = min { (C(Si) / CSUM) / W(Si)}  (i=0, 1, . , n-1)

  其中W(Si)不爲零

因爲CSUM在這一輪查找中是個常數,所以判斷條件可以簡化爲

  C(Sm) / W(Sm) = min { C(Si) / W(Si)}  (i=0, 1, . , n-1)

  其中W(Si)不爲零

因爲除法所需的CPU週期比乘法多,且在Linux內核中不允許浮點除法,服務器的

權值都大於零,所以判斷條件C(Sm) / W(Sm) > C(Si) / W(Si) 可以進一步優化

爲C(Sm)*W(Si) > C(Si)* W(Sm)。同時保證服務器的權值爲零時,服務器不被調

度。所以,算法只要執行以下流程。

for (m = 0; m < n; m++) {

if (W(Sm) > 0) {

for (i = m+1; i < n; i++) {

if (C(Sm)*W(Si) > C(Si)*W(Sm))

m = i;

}

return Sm;

}

}

 

基於局部性的最少鏈接(Locality-Based Least Connections Scheduling)

 

基於局部性的最少鏈接調度(Locality-Based Least Connections Scheduling,以下簡稱爲LBLC)算法是針對請求報文的目標IP地址的負載均衡調度,目前主要用於Cache集羣系統,因爲在Cache集羣中客戶請求報文的目標IP地址是變化的。這裏假設任何後端服務器都可以處理任一請求,算法的設計目標是在服務器的負載基本平衡情況下,將相同目標IP地址的請求調度到同一臺服務器,來提高各臺服務器的訪問局部性和主存Cache命中率,從而整個集羣系統的處理能力。

LBLC調度算法先根據請求的目標IP地址找出該目標IP地址最近使用的服務器,若該服務器是可用的且沒有超載,將請求發送到該服務器;若服務器不存在,或者該服務器超載且有服務器處於其一半的工作負載,則用“最少鏈接”的原則選出一個可用的服務器,將請求發送到該服務器。該算法的詳細流程如下:

LBLC調度算法流程

假設有一組服務器S = {S0, S1, ..., Sn-1},W(Si)表示服務器Si的權值,

C(Si)表示服務器Si的當前連接數。ServerNode[dest_ip]是一個關聯變量,表示

目標IP地址所對應的服務器結點,一般來說它是通過Hash表實現的。WLC(S)表示

在集合S中的加權最小連接服務器,即前面的加權最小連接調度。Now爲當前系統

時間。

if (ServerNode[dest_ip] is NULL) then {

n = WLC(S);

if (n is NULL) then return NULL;

ServerNode[dest_ip].server = n;

} else {

n = ServerNode[dest_ip].server;

if ((n is dead) OR

    (C(n) > W(n) AND

    there is a node m with C(m) < W(m)/2))) then {

n = WLC(S);

if (n is NULL) then return NULL;

ServerNode[dest_ip].server = n;

}

}

ServerNode[dest_ip].lastuse = Now;

return n;

此外,對關聯變量ServerNode[dest_ip]要進行週期性的垃圾回收(Garbage Collection),將過期的目標IP地址到服務器關聯項進行回收。過期的關聯項是指哪些當前時間(實現時採用系統時鐘節拍數jiffies)減去最近使用時間超過設定過期時間的關聯項,系統缺省的設定過期時間爲24小時。

 

帶複製的基於局部性最少鏈接(Locality-Based Least Connections with Replication Scheduling)

帶複製的基於局部性最少鏈接調度(Locality-Based Least Connections with Replication Scheduling,以下簡稱爲LBLCR)算法也是針對目標IP地址的負載均衡,目前主要用於Cache集羣系統。它與LBLC算法的不同之處是它要維護從一個目標IP地址到一組服務器的映射,而LBLC算法維護從一個目標IP地址到一臺服務器的映射。對於一個“熱門”站點的服務請求,一臺Cache 服務器可能會忙不過來處理這些請求。這時,LBLC調度算法會從所有的Cache服務器中按“最小連接”原則選出一臺Cache服務器,映射該“熱門”站點到這臺Cache服務器,很快這臺Cache服務器也會超載,就會重複上述過程選出新的Cache服務器。這樣,可能會導致該“熱門”站點的映像會出現在所有的Cache服務器上,降低了Cache服務器的使用效率。LBLCR調度算法將“熱門”站點映射到一組Cache服務器(服務器集合),當該“熱門”站點的請求負載增加時,會增加集合裏的Cache服務器,來處理不斷增長的負載;當該“熱門”站點的請求負載降低時,會減少集合裏的Cache服務器數目。這樣,該“熱門”站點的映像不太可能出現在所有的Cache服務器上,從而提供Cache集羣系統的使用效率。

LBLCR算法先根據請求的目標IP地址找出該目標IP地址對應的服務器組;按“最小連接”原則從該服務器組中選出一臺服務器,若服務器沒有超載,將請求發送到該服務器;若服務器超載;則按“最小連接”原則從整個集羣中選出一臺服務器,將該服務器加入到服務器組中,將請求發送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服務器從服務器組中刪除,以降低複製的程度。LBLCR調度算法的流程如下:

LBLCR調度算法流程

假設有一組服務器S = {S0, S1, ..., Sn-1},W(Si)表示服務器Si的權值,

C(Si)表示服務器Si的當前連接數。ServerSet[dest_ip]是一個關聯變量,表示

目標IP地址所對應的服務器集合,一般來說它是通過Hash表實現的。WLC(S)表示

在集合S中的加權最小連接服務器,即前面的加權最小連接調度;WGC(S)表示在

集合S中的加權最大連接服務器。Now爲當前系統時間,lastmod表示集合的最近

修改時間,T爲對集合進行調整的設定時間。

if (ServerSet[dest_ip] is NULL) then {

n = WLC(S);

if (n is NULL) then return NULL;

add n into ServerSet[dest_ip];

} else {

n = WLC(ServerSet[dest_ip]);

if ((n is NULL) OR

    (n is dead) OR

    (C(n) > W(n) AND

    there is a node m with C(m) < W(m)/2))) then {

n = WLC(S);

if (n is NULL) then return NULL;

add n into ServerSet[dest_ip];

} else

if (|ServerSet[dest_ip]| > 1 AND

    Now - ServerSet[dest_ip].lastmod > T) then {

m = WGC(ServerSet[dest_ip]);

remove m from ServerSet[dest_ip];

}

}

ServerSet[dest_ip].lastuse = Now;

if (ServerSet[dest_ip] changed) then

ServerSet[dest_ip].lastmod = Now;

return n;

此外,對關聯變量ServerSet[dest_ip]也要進行週期性的垃圾回收(Garbage Collection),將過期的目標IP地址到服務器關聯項進行回收。過期的關聯項是指哪些當前時間(實現時採用系統時鐘節拍數jiffies)減去最近使用時間(lastuse)超過設定過期時間的關聯項,系統缺省的設定過期時間爲24小時。

 

目標地址散列調度(Destination Hashing Scheduling)

 

目標地址散列調度(Destination Hashing Scheduling)算法也是針對目標IP地址的負載均衡,但它是一種靜態映射算法,通過一個散列(Hash)函數將一個目標IP地址映射到一臺服務器。

目標地址散列調度算法先根據請求的目標IP地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,否則返回空。該算法的流程如下:

目標地址散列調度算法流程

假設有一組服務器S = {S0, S1, ..., Sn-1},W(Si)表示服務器Si的權值,

C(Si)表示服務器Si的當前連接數。ServerNode[]是一個有256個桶(Bucket)的

Hash表,一般來說服務器的數目會運小於256,當然表的大小也是可以調整的。

算法的初始化是將所有服務器順序、循環地放置到ServerNode表中。若服務器的

連接數目大於2倍的權值,則表示服務器已超載。

n = ServerNode[hashkey(dest_ip)];

if ((n is dead) OR

(W(n) == 0) OR

    (C(n) > 2*W(n))) then

return NULL;

return n;

在實現時,我們採用素數乘法Hash函數,通過乘以素數使得散列鍵值儘可能地達到較均勻的分佈。所採用的素數乘法Hash函數如下:

素數乘法Hash函數

static inline unsigned hashkey(unsigned int dest_ip)

{

    return (dest_ip* 2654435761UL) & HASH_TAB_MASK;

}

其中,2654435761UL是2到2^32 (4294967296)間接近於黃金分割的素數,

  (sqrt(5) - 1) / 2 =  0.618033989

  2654435761 / 4294967296 = 0.618033987

 

源地址散列調度(Source Hashing Scheduling)

 

源地址散列調度(Source Hashing Scheduling)算法正好與目標地址散列調度算法相反,它根據請求的源IP地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,否則返回空。它採用的散列函數與目標地址散列調度算法的相同。它的算法流程與目標地址散列調度算法的基本相似,除了將請求的目標IP地址換成請求的源IP地址,所以這裏不一一敘述。

在實際應用中,源地址散列調度和目標地址散列調度可以結合使用在防火牆集羣中,它們可以保證整個系統的唯一出入口。

 

 

參考:LVS中文站點 http://zh.linuxvirtualserver.org

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章