返回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官方手冊給的加權調度算法公式:後端
假設有一組服務器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
記住三個權重調度規則:
1.先約分
2.從最大權重開始調度
3.同權重的後端,從前向後調度blog
例如,三臺後端A:B:C=2:3:4
。這裏無法約分。get
A:B:C=2:3:3
,B和C權重相同,從B開始調度A:B:C=2:2:3
,因此下次調度CA:B:C=2:2:2
,下次從A開始A:B:C=1:2:2
A:B:C=1:1:2
A:B:C=1:1:1
A:B:C=0:1:1
A:B:C=0:0:1
A:B:C=0:0:0
因此,每一個調度循環的調度順序爲:CBCABCABC變量
調度過程以下圖:
再給個示例,A:B:C:D=2:4:6:8
首先約分,獲得A:B:C:D=1:2:3:4
因此,調度順序是DCDBCDABCD。
之前nginx的wrr調度算法和lvs的算法相似,都是直接剃短高權重節點的權重值,最後趨於均衡。但這樣的算法實際上對請求而言並不均衡,好比a:b:c = 5:1:1
,調用的順序將是aaaaabc、aaaaabc,a將被連續屢次調用。
後來nginx的wrr算法改進了,變得更復雜一些,但更趨於調度均衡。
假設a:b:c=A:B:C
,算法是這樣的:
a:b:c=A-N:B:C
(A-N+A):(B+B):(C+C)
,而後選中最大的權重節點,假如選中B。選中以後,對選中的節點的權重減去總權重N,因而比例變爲(2A-N):(2B-N):2C
例如,a:b:c=4:3:2
的調度過程爲:總權重爲4+3+2=9
a:b:c=-5:3:2
a:b:c=-1:6:4
,選中b
a:b:c=-1:-3:4
a:b:c=3:0:6
,選中c
a:b:c=3:0:-3
a:b:c=7:3:-1
,選中a
a:b:c=-2:3:-1
a:b:c=2:6:1
,選中b
a:b:c=2:-3:1
a:b:c=6:0:3
,選中a
a:b:c=-3:0:3
a:b:c=1:3:5
,選中c
a:b:c=1:3:-4
a:b:c=5:6:-2
,選中b
a:b:c=5:-3:-2
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...