應用負載均衡之LVS(五):lvs和nginx的wrr加權調度算法規律分析

返回LVS系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.htmlhtml

 

加權調度算法(wrr)是一種很常見的調度算法。它們按照權重比例進行調度,但實際調度選中的節點順序可能和想象中並不同。它們有各自的算法支持,但不管什麼算法,對於a、b、c三個節點,若是它們的權重比例爲a:b:c=x:y:z,在節點都健康的狀況下,每一輪輪詢過程當中a老是被選中x次,b老是被選中y次,c老是被選中z次,只不過被選中的順序可能因算法不一樣而不一樣,nginx

因此,本文主要介紹lvs和nginx的wrr算法是如何計算的。算法

lvs的wrr調度算法

1.加權調度算法公式

首先,給一個LVS官方手冊給的加權調度算法公式:後端

假設有一組服務器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三個後端的權重比是2:3:4,那麼一個調度循環內的調度順序是CBCABCABC。code

若是你不想從算法公式裏找規律,那麼看下面。htm

2.加權調度通俗規律

記住三個權重調度規則:
1.先約分
2.從最大權重開始調度
3.同權重的後端,從前向後調度blog

例如,三臺後端A:B:C=2:3:4。這裏無法約分。get

  1. 調度C
    調度以後,比率變成A:B:C=2:3:3,B和C權重相同,從B開始調度
  2. 調度B
    調度以後,比率變成A:B:C=2:2:3,因此下次調度C
  3. 調度C
    調度以後,比率變成A:B:C=2:2:2,下次從A開始
    當權重所有調整到相同值時,就按照前後順序不斷循環,直到調度完全部權重
  4. 調度A,調度以後,比率變成A:B:C=1:2:2
  5. 調度B,調度以後,比率變成A:B:C=1:1:2
  6. 調度C,調度以後,比率變成A:B:C=1:1:1
  7. 調度A,調度以後,比率變成A:B:C=0:1:1
  8. 調度B,調度以後,比率變成A:B:C=0:0:1
  9. 調度C,調度以後,比率變成A:B:C=0:0:0
  10. 進入下一個調度循環,順序是:CBCABCABC

因此,每一個調度循環的調度順序爲:CBCABCABC變量

調度過程以下圖:

再給個示例,A:B:C:D=2:4:6:8

首先約分,獲得A:B:C:D=1:2:3:4

  1. 調度D
  2. 調度C
  3. 調度D
  4. 調度B
  5. 調度C
  6. 調度D
  7. 調度A
  8. 調度B
  9. 調度C
  10. 調度D

因此,調度順序是DCDBCDABCD。

nginx的wrr調度算法

之前nginx的wrr調度算法和lvs的算法相似,都是直接剃短高權重節點的權重值,最後趨於均衡。但這樣的算法實際上對請求而言並不均衡,好比a:b:c = 5:1:1,調用的順序將是aaaaabc、aaaaabc,a將被連續屢次調用。

後來nginx的wrr算法改進了,變得更復雜一些,但更趨於調度均衡。

假設a:b:c=A:B:C,算法是這樣的:

  1. 全部權重加總獲得總權重(total):A+B+C=N
  2. 第一個請求進來,選擇權重最大的。假設爲a,因而選中A。選中以後,對選中的節點的權重減去總權重N,因而如今的比例是a:b:c=A-N:B:C
  3. 第二個請求進入,將好比所有加上原始比例(eff_weight),獲得(A-N+A):(B+B):(C+C),而後選中最大的權重節點,假如選中B。選中以後,對選中的節點的權重減去總權重N,因而比例變爲(2A-N):(2B-N):2C
  4. 以後每一個請求進來,都首先加上原始比例,而後選擇權重最大的,並對最大的權重值減去總權重N。
  5. 每一輪詢的最後一次調度,都會使被選中的節點權重變爲N,其它權重變爲0,減去總權重以後所有變成0,使得下一輪輪詢調度開始,從新回到原始比例。

例如,a:b:c=4:3:2的調度過程爲:總權重爲4+3+2=9

  1. 第1個請求,a權重最大,選中a
    • 選中以後,比例變爲a:b:c=-5:3:2
  2. 第2個請求,加上原始比例,獲得a:b:c=-1:6:4,選中b
    • 選中以後,比例變爲a:b:c=-1:-3:4
  3. 第3個請求,加上原始比例,獲得a:b:c=3:0:6,選中c
    • 選中以後,比例變爲a:b:c=3:0:-3
  4. 第4個請求,加上原始比例,獲得a:b:c=7:3:-1,選中a
    • 選中以後,比例變爲a:b:c=-2:3:-1
  5. 第5個請求,加上原始比例,獲得a:b:c=2:6:1,選中b
    • 選中以後,比例變爲a:b:c=2:-3:1
  6. 第6個請求,加上原始比例,獲得a:b:c=6:0:3,選中a
    • 選中以後,比例變爲a:b:c=-3:0:3
  7. 第7個請求,加上原始比例,獲得a:b:c=1:3:5,選中c
    • 選中以後,比例變爲a:b:c=1:3:-4
  8. 第8個請求,加上原始比例,獲得a:b:c=5:6:-2,選中b
    • 選中以後,比例變爲a:b:c=5:-3:-2
  9. 第9個請求,加上原始比例,獲得a:b:c=9:0:0,選中a
    • 選中以後,比例變爲a:b:c=0:0:0

一輪循環完成,調度的順序是a b c a b a c b a,這輪循環完成以後,它們的比例變爲0:0:0,下一個請求到來,加上原始權重後回到原比例4:3:2

若是是兩後端節點,它們的比例爲3:1,它們的調度順序將是aaba aaba aaba...

相關文章
相關標籤/搜索