Dubbo負(fù)載均衡算法_第1頁
Dubbo負(fù)載均衡算法_第2頁
Dubbo負(fù)載均衡算法_第3頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、負(fù)載均衡算法在集群負(fù)載均衡時,Dubbo 提供了 4種均衡策略,如: Random LoadBalance(隨機(jī)均衡算法)、;Rou ndRobinLoadBala nce( 權(quán)重輪循均衡算法)、LeastActio nLoadBalance(最少活躍調(diào)用數(shù)均衡算法)、ConsistentHash LoadBalance(致性 Hash 均衡算法)。缺省時為Random 隨機(jī)調(diào)用。這四種算法的原理簡要介紹如下:1、RoundRobin LoadBalanceRou nd-Robin既是輪詢算法,是按照公約后的權(quán)重設(shè)置輪詢比率,即權(quán)重輪詢算法(Weighted Rou nd-Robi n),它是

2、基于輪詢算法改進(jìn)而來的。這里之所以寫Rou ndRobin是為了跟Dubbo中的內(nèi)容保持一致。輪詢調(diào)度算法的原理是:每一次把來自用戶的請求輪流分配給內(nèi)部中的服務(wù)器。女口:從1開始,一直到N(其中,N是內(nèi)部服務(wù)器的總個數(shù)),然后重新開始循環(huán)。該算法的優(yōu)點:其簡潔性,它無需記錄當(dāng)前所有連接的狀態(tài),所以它是一種無狀態(tài)調(diào)度。該算法的缺點:輪詢調(diào)度算法假設(shè)所有服務(wù)器的處理性能都相同,不關(guān)心每臺服務(wù)器的當(dāng)前連接數(shù)和響應(yīng)速度。當(dāng)請求服務(wù)間隔時間變化比較大時,輪詢調(diào)度算法容易導(dǎo)致服務(wù)器間的負(fù)載不平衡。所以此種均衡算法適合于服務(wù)器組中的所有服務(wù)器都有相同的軟硬件配置并且平均服 務(wù)請求相對均衡的情況。但是,在實際

3、情況中,可能并不是這種情況。由于每臺服務(wù)器的配置、安裝的業(yè)務(wù)應(yīng)用等不同, 其處理能力會不一樣。 所以,我們根據(jù)服務(wù)器的不同處理能力, 給每個服務(wù)器分配不同的權(quán)值,使其能夠接受相應(yīng)權(quán)值數(shù)的服務(wù)請求。權(quán)重輪詢調(diào)度算法流程假設(shè)有一組服務(wù)器 S = SO, S1,Sn-1 , W(Si)表示服務(wù)器Si的權(quán)值,一個指示變量i表示上一次選擇的服務(wù)器,指示變量 cw表示當(dāng)前調(diào)度的權(quán)值, max(S)表示集合S中所有 服務(wù)器的最大權(quán)值,gcd(S)表示集合S中所有服務(wù)器權(quán)值的最大公約數(shù)。 變量i初始化為-1 , cw初始化為零。其算法如下:while (true) i = (i + 1) mod n;if (

4、i = 0) cw = cw - gcd(S);if (cw <= 0) cw = max(S);if (cw = 0)return NULL;if (W(Si) >= cw)return Si;這種算法的邏輯實現(xiàn)如圖2所示,圖中我們假定四臺服務(wù)器的處理能力為3:1:1:1。負(fù)載均衡算法一枚重輪詢調(diào)度客戶端管理員段M把客戶的堵 求按3比例分配路山器於範(fàn)均衡器圖1權(quán)重輪詢調(diào)度實現(xiàn)邏輯圖示由于權(quán)重輪詢調(diào)度算法考慮到了不同服務(wù)器的處理能力,所以這種均衡算法能確保高性能的服務(wù)器得到更多的使用率,避免低性能的服務(wù)器負(fù)載過重。所以,在實際應(yīng)用中比較常 見。2、ConsistentHash Lo

5、adBalance一致性Hash,相同參數(shù)的請求總是發(fā)到同一個提供者。一:一致性 Hash算法可以解 決服務(wù)提供者的增加、移除及掛掉時的情況,能盡可能小的改變已存在 key映射關(guān)系,盡可能的滿足單調(diào)性的要求。二:一致性Hash通過構(gòu)建虛擬節(jié)點,能盡可能避免分配失衡,具有很好的平衡性。一致性Hash下面就來按照 5個步驟簡單講講 consistent hash 算法的基本原理。因 為以下資料來自于互聯(lián)網(wǎng),現(xiàn)說明幾點:一、下面例子中的對象就相當(dāng)于Client發(fā)的請求,cache相當(dāng)于服務(wù)提供者。環(huán)形hash空間考慮通常的hash算法都是將value 映射到一個32為的key值,也即是02人32-1

6、次方的數(shù)值空間;我們可以將這個空間想象成一個首(0)尾(2人32-1)相接的圓環(huán),如下面圖2所示的那樣。圖2環(huán)形hash空間把對象映射到hash空間接下來考慮 4個對象 object1object4 ,通過 hash 函數(shù)計算出的 hash 值key 在環(huán)上的分布如圖3所示。hash(object1) = key1;hash(object4) = key4;圖34個對象的key值分布把cache映射到hash空間Consistent hashing的基本思想就是將對象和cache都映射到同一個hash數(shù)值空間中,并且使用相同的hash算法。假設(shè)當(dāng)前有A,B和C共3臺cache,那么其映射結(jié)果將

7、如圖4所示,他們在hash空間中,以對應(yīng)的 hash值排列。hash(cache A) = key A;hash(cache C) = key C;圖4 cache和對象的 key值分布說到這里,順便提一下 cache的hash計算,一般的方法可以使用cache機(jī)器的IP地址或者機(jī)器名作為hash輸入。把對象映射到cache現(xiàn)在cache和對象都已經(jīng)通過同一個hash算法映射到 hash數(shù)值空間中了,接下來要考慮的就是如何將對象映射到cache上面了。在這個環(huán)形空間中,如果沿著順時針方向從對象的key值出發(fā),直到遇見一個 cache那么就將該對象存儲在這個cache上,因為對象和 cache的

8、hash值是固定的,因此這個cache必然是唯一和確定的。這樣不就找到了對象和cache的映射方法了嗎!依然繼續(xù)上面的例子(參見圖 4),那么根據(jù)上面的方法,對象objectl將被存儲到cache A 上;object2 和 object3 對應(yīng)到 cache C ; object4 對應(yīng)到 cache B ;考察cache 的變動前面講過,一致性Hash算法可以解決服務(wù)提供者的增加、移除及掛掉時的情況,能盡可能小的改變已存在 key映射關(guān)系,盡可能的滿足單調(diào)性的要求。移除cache考慮假設(shè) cache B掛掉了,根據(jù)上面講到的映射方法,這時受影響的將僅是那些沿cache B逆時針遍歷直到下一

9、個cache ( cache C )之間的對象,也即是本來映射到cache B 上的那些對象。因此這里僅需要變動對象object4,將其重新映射到cache C 上即可;參見圖 5 。cbjecilCache CCaciw S圖5 Cache B 被移除后的 cache 映射添力口 cache再考慮添加一臺新的cache D的情況,假設(shè)在這個環(huán)形hash 空間中,cache D 被cache D 逆時針遍歷cache C上對象的映射在對象 object2 和object3 之間。這時受影響的將僅是那些沿直到下一個 cache ( cache B )之間的對象(它們是也本來映射到部分),將這些對

10、象重新映射到cache D上即可。因此這里僅需要變動對象object2 ,將其重新映射到cache D 上;參見圖 6 。圖6 添加cache D 后的映射關(guān)系虛擬節(jié)點考慮Hash算法的另一個指標(biāo)是平衡性(Balanee),定義如下:平衡性是指哈希的結(jié)果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用。hash算法并不是保證絕對的平衡,如果 到 cache上,比如在上面的例子中,僅部署 象中,cache A僅存儲了 objectl ,而 object4 ;分布是很不均衡的。為了解決這種情況,con siste nt hash ingcache較少的話,對象并不能被均勻的映射

11、cache A 和cache C 的情況下,在 4個對cache C 則存儲了 object2 、 object3 和弓I入了“虛擬節(jié)點”的概念,它可以如下定義:"虛擬節(jié)點” (virtual node )是實際節(jié)點在 hash空間的復(fù)制品(replica ),- 實際個節(jié)點對應(yīng)了若干個“虛擬節(jié)點” ,這個對應(yīng)個數(shù)也成為“復(fù)制個數(shù)”,“虛擬節(jié)點”在 hash空間中以 hash值排列。仍以僅部署 cache A 和cache C 的情況為例,在圖 5中我們已經(jīng)看到,cache分布并不均勻?,F(xiàn)在我們引入虛擬節(jié)點,并設(shè)置“復(fù)制個數(shù)”為2,這就意味著一共會存在4 個“虛擬節(jié)點”,cache

12、A1, cache A2 代表了 cache A ; cache C1, cache C2 代表 了 cache C ;假設(shè)一種比較理想的情況,參見圖 7。圖7引入“虛擬節(jié)點”后的映射關(guān)系此時,對象到“虛擬節(jié)點”的映射關(guān)系為:objec1->cache A2 ; objec2->cache A1 ; objec3->cache C1 ; objec4->cache C2因此對象 objectl 和object2 都被映射到了 cache A 上,而object3 和object4 映射到了 cache C上;平衡性有了很大提高。引入“虛擬節(jié)點”后,映射關(guān)系就從對象-&g

13、t; 節(jié)點轉(zhuǎn)換到了 對象-> 虛擬節(jié)點。查詢物體所在cache時的映射關(guān)系如圖8所示。圖8查詢對象所在cache“虛擬節(jié)點”的hash計算可以采用對應(yīng)節(jié)點的IP地址加數(shù)字后綴的方式。例如假設(shè) cache A 的 IP 地址為 。引入"虛擬節(jié)點”前,計算cache A的hash值:Hash( “” );引入"虛擬節(jié)點”后,計算"虛擬節(jié)”點 cache A1 和cache A2 的hash值:Hash( “” ); / cache A1Hash( “” ); / cache A23、Random LoadBalance 與 LeastAction LoadBal

14、anceRandom LoadBalanee 與 LeastAction LoadBalanee 算法比較簡單,可以參照Dubbo文檔中的給的描述及后面代碼附錄。Dubbo文檔截圖如下圖9所示:負(fù)載均衡(>)(#)J左集群負(fù)載均循時,Dub曲唱侃T弊種均衢第疇玦省rancom機(jī)同弔亠可以自冇曠辰負(fù)戲吃備踰略,巒見;門或侈備廣.艮RiiJoiei LdiidEW口itce< fl扌Jb按牧垂遅養(yǎng)睡機(jī)規(guī)車在一于截面上碰H工糠衣頁但調(diào)毎星捱大分布越均勻貢且頂般率使甲權(quán)重后也比嫌的勻有刑于訖惡謂望餐恨者臥垂RniinriRobin LcariBalriricp皂儲,推處釣恬的枝里設(shè)蓋耘脩比

15、率。存相隍的哩哄音累稅請求同題,比如:鑒二臺機(jī)器僱慢,但沒掛口當(dāng)青術(shù)調(diào)剁莊二臺村議卡枉抑,復(fù)而憂;t,屬有育求律累在調(diào)到霜二白上,LeajWctive LoodEJalance最少酒眾調(diào)用裁,柜同若聶數(shù)的櫃tfb活樂敎指瀾用前后計埶養(yǎng)??斐痰奶崃险呤盏杰嚿僬?zhí)O因泊擔(dān)慢的檸供者的調(diào)用前后計裁姜套越大。CoiKist&ntHh LcaHRaGi心t -mtH3?h.同諏酣新潔求星帚方剽同一掃書看*冷棊一自提陰書掛時,療本發(fā)往諉提陜耆時請求,節(jié)點,平龍劃其Ea-不去弓I起劇烈變動- 尊達(dá)奮見:http ' en.wikipodifl arg m ki/Co na istaithash

16、 mg * 玦譽(yù)H對Ji一個按韌由$八 如黑更修禎 + iI3?3<riiihno oarantrke-.='T3h arjurripnls' values"0 1' >* 缺皆鳧 1 肌怕劉口節(jié)點如果10?S<dLbDo.par3meter y= hash.rrodes ue=F320 ,/>圖9負(fù)載均衡算法4、附錄1、RandomLoadBalanee算法public class RandomLoadBalaneeexte nds AbstractLoadBala nee public static final String NAM

17、E = "random"private final Random random = new Random();protected <T>In voker<T>ist< In voker<T>>invokers,URL url,In vocati on in vocati on) int length = invokers.size();/ 總個數(shù)int totalWeight = 0;/ 總權(quán)重boolean sameWeight = true ; / 權(quán)重是否都一樣for (int i = 0; i < length;

18、 i+) int weight = getWeight(invokers.get(i), invocation);totalWeight += weight; / 累計總權(quán)重if (sameWeight && i > 0&& weight != getWeight(i nvokers.get(i - 1), in vocatio n) sameWeight = false ; /計算所有權(quán)重是否一樣if (totalWeight > 0 && ! sameWeight) /如果權(quán)重不相同且權(quán)重大于0則按總權(quán)重數(shù)隨機(jī)int offset

19、 =random .nextInt(totalWeight);/并確定隨機(jī)值落在哪個片斷上 for (int i = 0; i < length; i+) offset -= getWeight(i nvokers.get(i), i nvocati on);if (offset < 0) retur nin vokers.get(i);/如果權(quán)重相同或權(quán)重為0則均等隨機(jī)return in vokers.get(ran dom .n ext In t(le ngth);2、RoundRobinLoadBalanee算法public class RoundRobinLoadBalan

20、eeextends AbstractLoadBalanee public static final String NAME = "roundrobin"private final ConcurrentMapvString, AtomicPositiveInteger>sequences =new ConcurrentHashMapvString, AtomicPositiveInteger>();private final ConcurrentMapvString, AtomicPositiveInteger>weightSequencesnew Conc

21、urrentHashMapvString, AtomicPositiveInteger>();protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url,In vocati on in vocati on) Stri ng key = in vokers.get(O).getUrl().getServiceKey() +"." +in vocatio n.getMethodName();int length = invokers.size();

22、 / 總個數(shù)int maxWeight = 0;/ 最大權(quán)重int minWeight = Integer. MAX_VALUE ; / 最小權(quán)重for (int i = 0; i < length; i+) int weight = getWeight(invokers.get(i), invocation);maxWeight = Math.max (maxWeight, weight);/累計最大權(quán)重mi nWeight = Math.min (minWeight,weight);/累計最小權(quán)重/權(quán)重不一樣weightSeque nces.get(key);if (maxWeigh

23、t > 0 && mi nWeight < maxWeight) AtomicPositive In teger weightSeque nee =if (weightSequenee =null ) weightSeque nces.putIfAbse nt(key.new AtomicPositivelnteger();weightSeque nee =weightSeque nces.get(key);int currentWeight = weightSequence.getAndlncrement() % maxWeight;List< In vok

24、er<T>> weight In vokers =new ArrayList<I nvoker<T>>();for (Invoker<T> invoker : invokers) / 篩選權(quán)重大于當(dāng)前權(quán)重基數(shù)的Invokerif (getWeight(i nvoker, i nvocati on) > curre ntWeight) weightI nvokers.add(i nvoker);int weightLength = weightInvokers.size();if (weightLe ngth = 1) return w

25、eightI nvokers.get(O); else if (weightLength > 1) in vokers = weightI nvokers; len gth = in vokers.size();sequences .get(key);AtomicPositive In teger seque nee =if(seque nee =null ) sequences.putlfAbsent(key,new AtomicPositivelnteger();sequenee =sequences .get(key);/取模輪循retur nin vokers.get(seque

26、 nce.getA ndln creme nt() % len gth);3、LeastActionLoadBalanee算法public class LeastActiveLoadBalaneeextendsAbstractLoadBalanee public static final String NAME = "leastactive"private final Randomrandom = new Random();protected <T> Invoker<T> doSelect(List<Invoker<T>> i

27、nvokers, URL url,In vocati on in vocati on) int length = invokers.size();/ 總個數(shù)int leastActive = -1;/ 最小的活躍數(shù)int leastCount = 0;/相同最小活躍數(shù)的個數(shù)in t least In dexs =new in t le ngth; / 相同最小活躍數(shù)的下標(biāo)int totalWeight = 0;/ 總權(quán)重int firstWeight = 0;/第一個權(quán)重,用于于計算是否相同booleansameWeight =true ; / 是否所有權(quán)重相同for (int i = 0;

28、i < length; i+) In voker<T> in voker = in vokers.get(i);int active = RpcStatus.getStatus (invoker.getUrl(),in vocatio n.getMethodName().getActive();/活躍數(shù)int weight =in voker.getUrl().getMethodParameter(i nvocati on. getMethodName(),Con sta nts. WEIGHT_KEY, Con sta nts.DEFAULT_WEIGHT); / 權(quán)重if

29、 (leastActive = -1 | active < leastActive) / 發(fā)現(xiàn)更小的活躍數(shù),重新開始leastActive = active;/記錄最小活躍數(shù)leastCou nt = 1;/重新統(tǒng)計相冋最小活躍數(shù)的個數(shù)least In dexs0 = i;/重新記錄最小活躍數(shù)下標(biāo)totalWeight = weight;/重新累計總權(quán)重firstWeight = weight;/記錄第一個權(quán)重sameWeight = true ; /還原權(quán)重相同標(biāo)識 else if (active = leastActive) / 累計相同最小的活躍數(shù)leastIndexsleastC

30、ount + = i;/累計相同最小活躍數(shù)下標(biāo)totalWeight += weight;/ 累計總權(quán)重/判斷所有權(quán)重是否一樣if (sameWeight && i > 0&& weight != firstWeight) sameWeight =false ;/ assert(leastCou nt > 0)if (leastCou nt = 1) /如果只有一個最小則直接返回retur n in vokers.get(leastl ndexs0);if (! sameWeight && totalWeight > 0) /如

31、果權(quán)重不相同且權(quán)重大于0則按總權(quán)重數(shù)隨機(jī)int offsetWeight =random .nextInt(totalWeight);/并確定隨機(jī)值落在哪個片斷上 for (int i = 0; i < leastCount; i+) int leastIndex = leastIndexsi;offsetWeight -= getWeight(i nvokers.get(leastl ndex), i nvocati on); if (offsetWeight <= 0)retur nin vokers.get(least In dex);/如果權(quán)重相同或權(quán)重為0則均等隨機(jī)ret

32、ur n in vokers.get(least In dexsran dom.n ext In t(leastCou nt);4、ConsistentHashLoadBalanee算法public class ConsistentHashLoadBalaneeextends AbstractLoadBalanee private final ConcurrentMapvString. ConsistentHashSelector<?>>selectors =new ConcurrentHashMapvString. ConsistentHashSelector<?&g

33、t;>();SuppressWar nings("u nchecked")Overrideprotected <T> Invoker<T> doSelect(List<lnvoker<T>> invokers, URL url,In vocati on in vocati on) Stri ng key = in vokers.get(O).getUrl().getServiceKey() +"." +in vocatio n.getMethodName();int identityHashCode

34、= System.identityHashCode(invokers);Con siste ntHashSelector<T> selector = (Con siste ntHashSelector<T>)selectors .get(key);if (selector = null | selector.getldentityHashCode。!= identityHashCode) selectors .put(key, new ConsistentHashSelector<T>(invokers,in vocatio n.getMethodName(

35、), ide ntityHashCode);selector = (ConsistentHashSelector<T>)selectors .get(key);retur n selector.select(i nvocati on);private static final class ConsistentHashSelector<T> private final TreeMap<Long. Invoker<T>>virtuallnvokers ;privatefinalintreplicaNumberprivatefinalintide nt

36、ityHashCodeprivatefinalint argume ntl ndexintpublic Con siste ntHashSelector(List<l nvoker<T>> in vokers, Stri ng methodName, ide ntityHashCode) this .virtualInvokers= new TreeMapvLong, Invoker<T>>();this .identityHashCode= System. identityHashCode (invokers);URL url = in vokers

37、.get(O).getUrl();this .replicaNumber = url.getMethodParameter(methodName,"hash .n odes" , 160);Str in g in dex =Constants. COMMA_SPLIT_PATTERN .split(url.getMethodParameter(methodName,"hash.arguments" , "0");argumentlndex= new int index. length ;for (int i = 0; i < i

38、ndex.length ; i +) argumentlndexi = Integer.parseInt (indexi);for (Invoker<T> invoker : invokers) for (int i = 0; i < replicaNumber / 4; i+) byte digest = md5(invoker.getUrl().toFullString() + i);for (int h = 0; h < 4; h+) long m = hash(digest, h);virtuall nvokers.put(m, i nvoker);public int getldentityHashCode() retur n ide ntityHashCode ;public In voker<T> select(I nvocati on in vocati on) Stri ng key = toKey(i nvocati on. getArgume nts();byte digest = md5(key);In

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論