負載均衡的基本算法


負載均衡的基本算法,主要有以下幾種(參考F5產品):

  • 隨機:負載均衡方法隨機的把負載分配到各個可用的服務器上,通過隨機數生成算法選取一個服務器,然后把連接發送給它。雖然許多均衡產品都支持該算法,但是它的有效性一直受到質疑,除非把服務器的可運行時間看的很重。
  • 輪詢:輪詢算法按順序把每個新的連接請求分配給下一個服務器,最終把所有請求平分給所有的服務器。輪詢算法在大多數情況下都工作的不錯,但是如果負載均衡的設備在處理速度、連接速度和內存等方面不是完全均等,那么效果會更好。
  • 加權輪詢:該算法中,每個機器接受的連接數量是按權重比例分配的。這是對普通輪詢算法的改進,比如你可以設定:第三台機器的處理能力是第一台機器的兩倍,那么負載均衡器會把兩倍的連接數量分配給第3台機器。
  • 動態輪詢:類似於加權輪詢,但是,權重值基於對各個服務器的持續監控,並且不斷更新。這是一個動態負載均衡算法,基於服務器的實時性能分析分配連接,比如每個節點的當前連接數或者節點的最快響應時間等。
  • 最快算法:最快算法基於所有服務器中的最快響應時間分配連接。該算法在服務器跨不同網絡的環境中特別有用。
  • 最少連接:系統把新連接分配給當前連接數目最少的服務器。該算法在各個服務器運算能力基本相似的環境中非常有效。
  • 觀察算法:該算法同時利用最小連接算法和最快算法來實施負載均衡。服務器根據當前的連接數和響應時間得到一個分數,分數較高代表性能較好,會得到更多的連接。
  • 預判算法:該算法使用觀察算法來計算分數,但是預判算法會分析分數的變化趨勢來判斷某台服務器的性能正在改善還是降低。具有改善趨勢的服務器會得到更多的連接。該算法適用於大多數環境。

性能調優社區dynatrace在其博客中分享了客戶案例,電商網站在假日客流峰值期間數次崩潰,經過SQL優化和調整負載均衡算法解決了相關問題.首先要分析執行最慢的數據庫語句,並做性能優化,比如增加索引等。同時也優化了連接池大小來滿足高峰時刻的需求。然后,企業把負載均衡器的算法從Round-Robin改為了Least-Busy。

相關文章:

電商網站的宕機案例分析

ASP.NET Session State Partitioning

ASP.NET Session State Partitioning using State Server Load Balancing

解析nginx負載均衡

Round Robin Scheduling

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace LoadBalancer
{
    public class LoadBalance
    {
        /// <summary>
        /// 鎖對象
        /// </summary>
        private static readonly object locker = new object();

        /// <summary>
        /// 服務器權重列表
        /// </summary>
        private static List<int> weightList = new List<int>();

        /// <summary>
        /// 當前索引
        /// </summary>
        private static int currentIndex;

        /// <summary>
        /// 當前權重
        /// </summary>
        private static int currentWeight;

        private static int maxWeight;

        /// <summary>
        /// 最大公約數
        /// </summary>
        private static int gcd;

        static LoadBalance()
        {
            currentIndex = -1;
            currentWeight = 0;

            //獲取服務器權重列表,從配置文件
            weightList = GetWeightList();
            maxWeight = GetMaxWeight(weightList);
            gcd = GetMaxGCD(weightList);
        }

        private static List<int> GetWeightList()
        {
            List<int> list = new List<int>();
            list.Add(3);
            list.Add(1);
            list.Add(1);
            list.Add(4);
            list.Add(1);
            list.Add(7);

            return list;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static int Start()
        {
            lock (locker)
            {
                int? iWeight = RoundRobin();
                if (iWeight != null)
                {
                    return (int)iWeight;
                }
                return weightList[0];
            }
        }


        /// <summary>
        /// 獲取最大公約數
        /// </summary>
        /// <param name="list">要查找的int集合</param>
        /// <returns>返回集合中所有數的最大公約數</returns>
        private static int GetMaxGCD(List<int> list)
        {
            list.Sort(new WeightCompare());

            int iMinWeight = weightList[0];

            int gcd = 1;

            for (int i = 1; i < iMinWeight; i++)
            {
                bool isFound = true;
                foreach (int iWeight in list)
                {
                    if (iWeight % i != 0)
                    {
                        isFound = false;
                        break;
                    }
                }
                if (isFound) gcd = i;
            }
            return gcd;
        }


        /// <summary>
        /// 獲取服務器權重集合中的最大權重
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private static int GetMaxWeight(List<int> list)
        {
            int iMaxWeight = 0;
            foreach (int i in list)
            {
                if (iMaxWeight < i) iMaxWeight = i;
            }
            return iMaxWeight;
        }

        private static int? RoundRobin()
        {
            while (true)
            {
                currentIndex = (currentIndex + 1) % weightList.Count;
                if (0 == currentIndex)
                {
                    currentWeight = currentWeight - gcd;
                    if (0 >= currentWeight)
                    {
                        currentWeight = maxWeight;
                        if (currentWeight == 0) return null;
                    }
                }

                if (weightList[currentIndex] >= currentWeight)
                {
                    return weightList[currentIndex];
                }
            }
        }

    }

    public class WeightCompare : IComparer<int>
    {
        public int Compare(int x, int y)
        {
            return x - y;
        }
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM