dubbo第三課(dubbo負載均衡)

負載均衡


負載均衡,它的職責是將網絡請求,或者其他形式的負載“均攤”到不同的機器上。避免集羣中部分服務器壓力過大,而另一些服務器比較空閒的情況。通過負載均衡,可以讓每臺服務器獲取到適合自己處理能力的負載。在爲高負載服務器分流的同時,還可以避免資源浪費,一舉兩得。負載均衡可分爲軟件負載均衡和硬件負載均衡。在我們日常開發中,一般很難接觸到硬件負載均衡。但軟件負載均衡還是可以接觸到的,比如 Nginx。

在 Dubbo 中,也有負載均衡的概念和相應的實現。Dubbo 需要對服務消費者的調用請求進行分配,避免少數服務提供者負載過大。服務提供者負載過大,會導致部分請求超時。

因此將負載均衡到每個服務提供者上,是非常必要的。Dubbo 提供了4種負載均衡實現,分別是基於權重隨機算法的 RandomLoadBalance、基於最少活躍調用數算法的 LeastActiveLoadBalance、基於 hash 一致性的 ConsistentHashLoadBalance,以及基於加權輪詢算法的 RoundRobinLoadBalance。

這幾個負載均衡算法代碼不是很長,但是想看懂也不是很容易,需要大家對這幾個算法的原理有一定了解纔行。如果不是很瞭解,也沒不用太擔心。我們會在分析每個算法的源碼之前,對算法原理進行簡單的講解,幫助大家建立初步的印象。

缺省爲random隨機調用.

Random LoadBalance

隨機,按權重設置隨機概率。

RandomLoadBalance 是加權隨機算法的具體實現,它的算法思想很簡單。假設我們有一組服務器 servers = [A, B, C],他們對應的權重爲 weights = [5, 3, 2],權重總和爲10。現在把這些權重值平鋪在一維座標值上,[0, 5) 區間屬於服務器 A,[5, 8) 區間屬於服務器 B,[8, 10) 區間屬於服務器 C。接下來通過隨機數生成器生成一個範圍在 [0, 10) 之間的隨機數,然後計算這個隨機數會落到哪個區間上。比如數字3會落到服務器 A 對應的區間上,此時返回服務器 A 即可。權重越大的機器,在座標軸上對應的區間範圍就越大,因此隨機數生成器生成的數字就會有更大的概率落到此區間內。只要隨機數生成器產生的隨機數分佈性很好,在經過多次選擇後,每個服務器被選中的次數比例接近其權重比例。比如,經過一萬次選擇後,服務器 A 被選中的次數大約爲5000次,服務器 B 被選中的次數約爲3000次,服務器 C 被選中的次數約爲2000次。

RoundRobin LoadBalance

輪循,按公約後的權重設置輪循比率。

我們先來了解一下什麼是加權輪詢。這裏從最簡單的輪詢開始講起,所謂輪詢是指將請求輪流分配給每臺服務器。舉個例子,我們有三臺服務器 A、B、C。我們將第一個請求分配給服務器 A,第二個請求分配給服務器 B,第三個請求分配給服務器 C,第四個請求再次分配給服務器 A。這個過程就叫做輪詢。輪詢是一種無狀態負載均衡算法,實現簡單,適用於每臺服務器性能相近的場景下。但現實情況下,我們並不能保證每臺服務器性能均相近。如果我們將等量的請求分配給性能較差的服務器,這顯然是不合理的。因此,這個時候我們需要對輪詢過程進行加權,以調控每臺服務器的負載。經過加權後,每臺服務器能夠得到的請求數比例,接近或等於他們的權重比。比如服務器 A、B、C 權重比爲 5:2:1。那麼在8次請求中,服務器 A 將收到其中的5次請求,服務器 B 會收到其中的2次請求,服務器 C 則收到其中的1次請求。

LeastActive LoadBalance

翻譯過來是最小活躍數負載均衡。活躍調用數越小,表明該服務提供者效率越高,單位時間內可處理更多的請求。此時應優先將請求分配給該服務提供者。在具體實現中,每個服務提供者對應一個活躍數 active。初始情況下,所有服務提供者活躍數均爲0。每收到一個請求,活躍數加1,完成請求後則將活躍數減1。在服務運行一段時間後,性能好的服務提供者處理請求的速度更快,因此活躍數下降的也越快,此時這樣的服務提供者能夠優先獲取到新的服務請求、這就是最小活躍數負載均衡算法的基本思想。除了最小活躍數,LeastActiveLoadBalance 在實現上還引入了權重值。所以準確的來說,LeastActiveLoadBalance 是基於加權最小活躍數算法實現的。舉個例子說明一下,在一個服務提供者集羣中,有兩個性能優異的服務提供者。某一時刻它們的活躍數相同,此時 Dubbo 會根據它們的權重去分配請求,權重越大,獲取到新請求的概率就越大。如果兩個服務提供者權重相同,此時隨機選擇一個即可。

ConsistentHash LoadBalance

該類是負載均衡基於 hash 一致性的邏輯實現。一致性哈希算法由麻省理工學院的 Karger 及其合作者於1997年提供出的,一開始被大量運用於緩存系統的負載均衡。它的工作原理是這樣的:首先根據 ip 或其他的信息爲緩存節點生成一個 hash,在dubbo中使用參數進行計算hash。並將這個 hash 投射到 [0, 232 - 1] 的圓環上,當有查詢或寫入請求時,則生成一個 hash 值。然後查找第一個大於或等於該 hash 值的緩存節點,併到這個節點中查詢或寫入緩存項。如果當前節點掛了,則在下一次查詢或寫入緩存時,爲緩存項查找另一個大於其 hash 值的緩存節點即可。大致效果如下圖所示(引用一下官網的圖)

每個緩存節點在圓環上佔據一個位置。如果緩存項的 key 的 hash 值小於緩存節點 hash 值,則到該緩存節點中存儲或讀取緩存項,這裏有兩個概念不要弄混,緩存節點就好比dubbo中的服務提供者,會有很多的服務提供者,而緩存項就好比是服務引用的消費者。比如下面綠色點對應的緩存項也就是服務消費者將會被存儲到 cache-2 節點中。由於 cache-3 掛了,原本應該存到該節點中的緩存項也就是服務消費者最終會存儲到 cache-4 節點中,也就是調用cache-4 這個服務提供者。

avatar

但是在hash一致性算法並不能夠保證hash算法的平衡性,就拿上面的例子來看,cache-3掛掉了,那該節點下的所有緩存項都要存儲到 cache-4 節點中,這就導致hash值低的一直往高的存儲,會面臨一個不平衡的現象,見下圖:

avatar

可以看到最後會變成類似不平衡的現象,那我們應該怎麼避免這樣的事情,做到平衡性,那就需要引入虛擬節點,虛擬節點是實際節點在 hash 空間的複製品,“虛擬節點”在 hash 空間中以hash值排列。比如下圖:

avatar

可以看到各個節點都被均勻分佈在圓環上,而某一個服務提供者居然有多個節點存在,分別跟其他節點交錯排列,這樣做的目的就是避免數據傾斜問題,也就是由於節點不夠分散,導致大量請求落到了同一個節點上,而其他節點只會接收到了少量請求的情況。類似第二張圖的情況。

連接超時timeout

毫秒爲單位 默認 1000

必須要設置服務的處理的超時時間

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