平滑的基於權重的輪詢演算法

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

輪詢演算法是非常常用的一種調度/負載平衡的演算法。依照百度百科上的解釋:

Round-Robin,輪詢調度,通訊中通道調度的一種策略,該調度策略使使用者輪流使用共用資源,不會考慮瞬時通道條件。從相同數量無線資源(相同調度時間段)被分配給每條通訊鏈路的角度講,輪詢調度可以被視為公平調度。然而,從提供相同服務品質給所有通訊鏈路的角度而言,輪詢調度是不公平的,此時,必須為帶有較差通道條件的通訊鏈路分配更多無線資源(更多時間)。此外,由於輪詢調度在調度過程中不考慮瞬時通道條件,因此它將導致較低的整體系統效能,但與最大載幹比調度相比,在各通訊鏈路間具有更為均衡的服務品質。

更廣泛的輪詢調度應用在廣度的服務調度上面,尤其在面向服務或者是面向微服務的架構中,比可以在很多知名的軟體中看到它的身影,比如LVS、Nginx、Dubblo等。但是正如上面的百度百科中的介紹一樣,輪詢調度有一個很大的問題,那就是它認為所有的服務的效能都是一樣的,每個伺服器都被公平的調度,在伺服器的效能有顯著差別的環境中,效能比較差的伺服器被調度了相同的次數,這不是我們所期望的。所以本文要介紹的是加權的輪詢演算法,輪詢演算法可以看成是加權的輪詢演算法的一個特例,在這種情況下,每個伺服器的權重都是一樣的。

本文介紹了Nginx和LVS的兩種演算法,比較了它們的優缺點,並提供了一個通用的 Go 語言實現的加權輪詢演算法庫: weighted,可以用在負載平衡/調度/微服務網關等場合。

WRR(weighted round-robin) 也是周而復始地輪詢分組服務資源,但不同的是WRR演算法為每個服務資源分派一個權值,當輪詢到某個服務的時候,將根據它所具有權值的大小決定其是否可以提供服務。由於WRR是基於輪詢的,因此它只是在大於一個輪詢周期的時間上才能顯示是公平的。

本文介紹了Nginx和LVS基於權重的輪詢演算法,這兩個演算法都是通過巧妙的運算得到每次要提供的服務物件,但各自又有自己的特點。

Nginx演算法

Nginx基於權重的輪詢演算法的實現可以參考它的一次代碼提交: Upstream: smooth weighted round-robin balancing。

它不但實現了基於權重的輪詢演算法,而且還實現了平滑的演算法。所謂平滑,就是在一段時間內,不僅伺服器被選擇的次數的分布和它們的權重一致,而且調度演算法還比較均勻的選擇伺服器,而不會集中一段時間之內只選擇某一個權重比較高的伺服器。如果使用隨機演算法選擇或者普通的基於權重的輪詢演算法,就比較容易造成某個服務集中被調用壓力過大。

舉個例子,比如權重為{a:5, b:1, c:1)的一組伺服器,Nginx的平滑的輪詢演算法選擇的序列為{ a, a, b, a, c, a, a },這顯然要比{ c, b, a, a, a, a, a }序列更平滑,更合理,不會造成對a伺服器的集中訪問。

演算法如下:

on each peer selection we increase current_weight of each eligible peer by its weight, select peer with greatest current_weight and reduce its current_weight by total number of weight points distributed
among peers.

1234567891011121314151617181920212223242526272829
func nextWeighted(servers []*Weighted) (best *Weighted) {total := 0for i := 0; i < len(servers); i++ {w := servers[i]if w == nil {continue}w.CurrentWeight += w.EffectiveWeighttotal += w.EffectiveWeightif w.EffectiveWeight < w.Weight {w.EffectiveWeight++}if best == nil || w.CurrentWeight > best.CurrentWeight {best = w}}if best == nil {return nil}best.CurrentWeight -= totalreturn best}

如果你使用weighted庫,你可以通過下面的幾行代碼就可以使用這個演算法進行調度:

123456789101112
func ExampleW_() {w := &W1{}w.Add("a", 5)w.Add("b", 2)w.Add("c", 3)for i := 0; i < 10; i++ {fmt.Printf("%s ", w.Next())}// Output: a c b a a c a b c a}

LVS演算法

LVS使用的另外一種演算法,它的演算法的介紹可以參考它的網站的wiki。

演算法用虛擬碼表示如下:

1234567891011121314151617181920
Supposing that there is a server set S = {S0, S1, …, Sn-1};W(Si) indicates the weight of Si;i indicates the server selected last time, and i is initialized with -1;cw is the current weight in scheduling, and cw is initialized with zero; max(S) is the maximum weight of all the servers in S;gcd(S) is the greatest common divisor of all server weights in S;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;}

可以看到它的代碼邏輯比較簡單,所以效能也很快,但是如果伺服器的權重差別較多,就不會像Nginx那樣比較平滑,可以在短時間內對權重很大的那台伺服器壓力過大。

使用weighted庫和上面一樣簡單,只是把類型W換成W2即可:

123456789101112
func ExampleW_() {w := &W2{}w.Add("a", 5)w.Add("b", 2)w.Add("c", 3)for i := 0; i < 10; i++ {fmt.Printf("%s ", w.Next())}// Output: a a a c a b c a b c}

效能比較

可以看到,上面兩種方法的使用都非常的簡單,只需產生一個相應的W對象,然後加入伺服器和對應的權重即可,通過Next方法就可以獲得下一個伺服器。

如果伺服器的權重差別很大,出於平滑的考慮,避免短時間內會對伺服器造成衝擊,你可以選擇Nginx的演算法,如果伺服器的差別不是很大,可以考慮使用LVS的演算法,因為測試可以看到它的效能要好於Nginx的演算法:

12
BenchmarkW1_Next-4      20000000                50.1 ns/op             0 B/op          0 allocs/opBenchmarkW2_Next-4      50000000                29.1 ns/op             0 B/op          0 allocs/op

實際上兩者的效能都非常的快,十個伺服器的每次調度也就是幾十納秒的層級,而且沒有額外的對象分配,所以無論使用哪種演算法,這個調度不應成為你整個系統的瓶頸。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.