LVS調度算法
內核中的連接調度算法
IPVS在內核中的負載均衡調度是以連接為粒度的。在HTTP協議(非持久中),每個對象從WEB服務器上獲取都需要建立一個TCP連接,同一用戶的不同請求會被調度到不同服務器上,所以這種細粒度的調度在一定程度上可以避免單個用戶訪問的突發性引起服務器間的負載不平衡。
在內核中的連接調度算法上,IPVS已實現了以下八種調度算法:
- 輪叫調度(Round-Robin Scheduling)
- 加權輪叫調度(Weighted Round-Robin Scheduling)
- 最小連接調度(Least-Connection Scheduling)
- 加權最小連接調度(Weighted Least-Connection Scheduling)
- 基於局部性的最少鏈接(Locality-Based Least Connections Scheduling)
- 帶復制的基於局部性最少鏈接(Locality-Based Least Connections with Replication Scheduling)
- 目標地址散列調度(Destination Hashing Scheduling)
- 源地址散列調度(Source Hashing Scheduling)
1、輪叫調度
該算法是以輪叫的方式依次將請求調度不同的服務器,即每次調度執行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;
輪叫調度算法假設所有服務器性能均相同,不管服務器當前連接數和響應速度,該算法簡單,不適用於服務器組中處理性能不一樣的情況,而且當請求服務時間比較大時,輪叫調度算法容易導致服務器間的負載不平衡。
2、加權輪叫調度
該算法可以解決服務器間性能不一的情況,它是相應的權值表示服務器的處理性能,服務器的缺省值為1。假設服務器A的權值為1,B的權值為2,則表示服務器的處理性能是A的兩倍。加權輪叫算法是按權值的高低和輪叫方式分配請求到各臺服務器。加權值高的先收到的連接,權值高的服務器處理更多的連接,相同權值的服務器處理相同的連接數。算法流程如下:
假設有一組服務器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; }
例如,有三個服務器A、B和C分別有權值4/3/2,則在一個調度周期內,順序為AABABCABC.次方法也比較簡單,高效。當請求的服務時間變化很大,單獨的加權輪叫調度算法依然會導致服務器之間負載不平衡
3、最小連接調度
該算法是將新的連接請求分配到當前連接數最小的服務器,最小調度是一種動態調度算法,它通過服務器當前所活躍的連接數來估計服務器的負載情況。調度器需要記錄各個服務器已連接的數目,當一個請求被調度到某臺服務器時,其連接數加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;
4、加權最小連接調度
該算法是最小連接調度的超集,各個服務器用相應的權值表示其處理能力。服務器的缺省值為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; } } return NULL;
參考:http://www.linuxvirtualserver.org/zh/lvs4.html
LVS調度算法