负载均衡算法,轮询方式

学无止境,精益求精

十年河东,十年河西,莫欺少年穷

学历代表你的过去,能力代表你的现在,学习代表你的将来

首先说下这个算法的背景:

假设公司需要存储的信息量非常非常大而且访问量也是非常非常滴大(例如淘宝,天猫,京东等数据存储量和访问量都很大)

就拿天猫来举例:

马云:小陈啊,最近公司业务发展,数据存储量及访问量灰常灰常大,为减轻服务器的负载,限你们技术部提出一个解决方案?

小陈:马大帅,你一个当老师的瞎操心什么技术(不屑的眼神)

马云:你知道杭州电子科技大学吗?

小陈:一脸懵逼...

马云:这所学校的前身是杭州师范学院 ~_~ 注:(马云从杭州师范学院外国语系英语专业毕业)

小陈:马大帅您竟然是电子科技大的高材生,佩服佩服。我马上召集技术部人员,集思广益。~_~ 注:(小陈并不知道马云英语专业毕业)

半小时后小陈提出了解决方案:负载均衡

要想做到负载均衡,就必须写一套负载均衡算法:

在介绍负载均衡算法之前,我们来介绍下负载均衡的使用场景,如下:

还是以阿里巴巴天猫举例:假设天猫只有一台数据库服务器,随着数据存储量及访问量的直线式增加,这台服务器的吞吐量达到了极值,造成了访问速度越来越慢。马总看到眼里,急在心里!于是就有了上述的对话!

小陈提出的负载均衡是怎么一回事呢?

把原来的一台服务器扩充至几十台或者几百台服务器,当第一台服务器吞吐量高时,将用户的请求转向第二台服务器。同理,当第二台服务器的吞吐量高时,将用户的请求转向第三台服务器,以此类推...

那么,如果自动做到负载均衡呢?这里就需要负载均衡的算法了!

假设:天猫总共有数据库服务器四台,每台服务器的性能不同,第一台可提供的最大连接数为2,第二台服务器可提供的最大连接数为4,第三台服务器可提供的最大连接数为8,最后一台为12

假设:现在可用的服务器为第三台和第四台。

负载均衡算法如下:

namespace SJMS.test
{
    public class Test
    {
        static int maxLinkCount;
        //
        private static object lockHelper = new object();
        /// <summary>
        /// 所有快照/服务器的权重列表 所谓权重我们可理解为最大连接数
        /// </summary>
        static List<int> snapWeightList = new List<int>() { 2,4,8,12};

        //可用的服务器权重列表
        static List<int> EnableWeightList = new List<int>() { 8,12 };
        /// <summary>
        /// 当前的快照索引和权重信息
        /// </summary>
        static int curentSnapIndex, currentWeight, EnableWeight;
        /// <summary>
        /// 快照权重列表中最大的权重值和最大公约数
        /// </summary>
        static int maxWeight, gcd;

        static Test()
        {
            curentSnapIndex = -1;
            currentWeight = 0;
            EnableWeight = 0;
            maxWeight = GetMaxWeight(snapWeightList);
            EnableWeight = GetMaxWeight(EnableWeightList);
            gcd = GCD(snapWeightList);
            maxLinkCount = EnableWeightList.Sum();
        }
        /// <summary>
        /// 获取最大值 权重
        /// </summary>
        /// <param name="snapWeightList"></param>
        /// <returns></returns>
        public static int GetMaxWeight(List<int> snapWeightList)
        {
            int maxWeight = 0;
            foreach (int snapWeight in snapWeightList)
            {
                if (maxWeight < snapWeight)
                    maxWeight = snapWeight;
            }
            return maxWeight;
        }

        /// <summary>
        /// 获取最大公约数
        /// </summary>
        /// <param name="snapWeightList"></param>
        /// <returns></returns>
        public static int GCD(List<int> snapWeightList)
        {
            // 排序,得到数字中最小的一个 
            snapWeightList.Sort(new WeightCompare());
            int minNum = snapWeightList[0];

            // 最大公约数肯定大于等于1,且小于等于最小的那个数。 
            // 依次整除,如果余数全部为0说明是一个约数,直到打出最大的那个约数 
            int gcd = 1;
            for (int i = 1; i <= minNum; i++)
            {
                bool isFound = true;
                foreach (int snapWeight in snapWeightList)
                {
                    if (snapWeight % i != 0)
                    {
                        isFound = false;
                        break;
                    }
                }
                if (isFound)
                    gcd = i;
            }
            return gcd;
        }

        /// <summary>
        /// 权重轮询调度算法/负载均衡算法
        /// </summary>
        public static int RoundRobinScheduling()
        {
            lock (lockHelper)
            {
                while (true)
                {
                    curentSnapIndex = (curentSnapIndex + 1) % EnableWeightList.Count;
                    if (curentSnapIndex == 0)
                    {
                        currentWeight = currentWeight - gcd;
                        if (currentWeight <= 0)
                        {
                            currentWeight = maxWeight;
                            if (currentWeight == 0)
                                return -1;
                        }
                    }
                    int A = snapWeightList[curentSnapIndex];
                    if (A >= currentWeight)
                    {
                        return EnableWeightList[curentSnapIndex];
                    }
                }
            }
        }
    }

    public class WeightCompare : System.Collections.Generic.IComparer<int>
    {
        public int Compare(int weightA, int weightB)
        {
            return weightA - weightB;
        }
    }

    public class DbSnapInfo
    {
        public int SouceID { get; set; }
        public bool Enable { get; set; }
        public int Weight { get; set; }
    }
}
View Code

这段代码有个比较难理解的地方:最大公约数的使用!(只可意会不可言传

要想弄清楚最大公约数的使用,建议大家多次调试(调试时:变更服务器及服务器连接数)。

 总之:算法的结果是帮你找到一个可用的服务器连接!

@陈卧龙的博客

原文地址:https://www.cnblogs.com/chenwolong/p/DbSnapInfo.html