你的位置:首页 > 数据库

[数据库]2种负载均衡算法


接口定义:

  public interface ILoadBalance<T>  {    T Balance();  }

实现:

  public class WeightObject<T> where T : class  {    int weight;    T activator;    public WeightObject(T activator, int weight)    {      Activator = activator;      Weight = weight;    }    public int Weight    {      get      {        return weight;      }      private set      {        if (value <= 0)        {          throw new ArgumentOutOfRangeException();        }        weight = value;      }    }    public T Activator    {      get      {        return activator;      }      private set      {        if (value == null)        {          throw new ArgumentNullException();        }        activator = value;      }    }  }  public class OrderLoadBalance<T> : ILoadBalance<T>  {    private readonly object syncRoot = new object();    private int gcd;    private int currentIndex = -1;    private int currentWeight = 0;    private int maxWeight;    private List<WeightObject<Func<T>>> list = new List<WeightObject<Func<T>>>();    public OrderLoadBalance(IEnumerable<WeightObject<Func<T>>> weightObjects)    {      list.AddRange(weightObjects);      gcd = GetGCD();      maxWeight = list.Select(w => w.Weight).Max();    }    private int GetGCD()    {      int gcd = 1;      int minWeight = list.Select(w => w.Weight).Min();      for (int i = 1; i < minWeight; i++)      {        bool isFound = true;        foreach (var weightObject in list)        {          if (weightObject.Weight % i != 0)          {            isFound = false;            break;          }        }        if (isFound) gcd = i;      }      return gcd;    }    [MethodImpl(MethodImplOptions.Synchronized)]    public T Balance()    {      lock (syncRoot)      {        while (true)        {          currentIndex = (currentIndex + 1) % list.Count;          if (0 == currentIndex)          {            currentWeight = currentWeight - gcd;            if (0 >= currentWeight)            {              currentWeight = maxWeight;              if (currentWeight == 0) return list[0].Activator();            }          }          if (list[currentIndex].Weight >= currentWeight)          {            return list[currentIndex].Activator();          }        }      }    }  }  public class RandomLoadBalance<T> : ILoadBalance<T>  {

private Random random; private int totalWeight; private List<WeightObject<Func<T>>> list = new List<WeightObject<Func<T>>>(); public RandomLoadBalance(IEnumerable<WeightObject<Func<T>>> weightObjects) { list.AddRange(weightObjects); totalWeight = list.Select(w => w.Weight).Sum(); random = new Random(); } public T Balance() { int r = random.Next(totalWeight) + 1; int weight = 0; foreach (var item in list) { weight += item.Weight; if (weight>=r) { return item.Activator(); } } return list[0].Activator();// } }

     以上两种方式均可以实现简单的均衡算法,第一种我参考许多前辈的写法,第二种属于自己想的.从概率论的角度出发都可以满足需求,而且两者效率相当(我原以为第二种实现方式速度更快,很遗憾的是结果证明并非如此,可能是Random对象取随机数比较慢,我理论上认为没有锁会更快的),我个人觉得方法二更好,理由是离散型更好,方法一虽然概率上不错,但是会连续密集的访问同一对象.作为一种均衡算法我觉得还是离散性高比较好,因为这样可以更好的错开密集访问!!!