如何使用c#实现加权循环?

发布于 2024-12-20 23:06:35 字数 123 浏览 2 评论 0原文

如果我有一些服务器:192.168.100.1、192.168.100.2、192.168.100.3、192.168.100.4... 它们的权重是:5,1,2,3

我想实现负载均衡,但是如何使用C#实现加权循环?

If I have some servers: 192.168.100.1, 192.168.100.2, 192.168.100.3, 192.168.100.4...
and weights of them are: 5, 1, 2, 3

I want to implement load balancing, but how can I implement weighted round robin using C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

请爱~陌生人 2024-12-27 23:06:35

假设您有服务器 abcd。并且您有相应的权重 5123。您可以通过以下方式进行加权循环:

Random rand = new Random(seed);

void processRequest(Request r){

    // assume rand.next() returns a uniformly distributed integer >= 0
    int i = rand.next() % 11; // 11 is sum of weights

    if(i <= 4)      // process r with server a
    else if(i == 5) // process r with server b
    else if(i <= 7) // process r with server c
    else            // process r with server d
}

rand.next() % 11 返回[0, 10](含)范围内的均匀分布整数。我们使用服务器 a 处理请求,获取五个可能的值 [0, 4]。我们使用服务器 b 处理请求,仅获取一个可能的值 5,依此类推。

请特别注意您使用的特定随机方法和种子值。

Say you have servers a, b, c, d. And you have corresponding weights 5, 1, 2, 3. You can do weighted round robin in the following way:

Random rand = new Random(seed);

void processRequest(Request r){

    // assume rand.next() returns a uniformly distributed integer >= 0
    int i = rand.next() % 11; // 11 is sum of weights

    if(i <= 4)      // process r with server a
    else if(i == 5) // process r with server b
    else if(i <= 7) // process r with server c
    else            // process r with server d
}

rand.next() % 11 returns a uniformly distributed integer in the range [0, 10] (inclusive). We process the request with server a for five of the possible values [0, 4]. We process the request with server b for only one possible value 5 and so on.

Pay special attention to the particular random method you use and the seed value.

開玄 2024-12-27 23:06:35

随机加权选择算法

// returns the index of the chosen one, note that the index starting with 0
static int randomWeightedSelect(List<int> colls) {
    int lucky = rand.Next(1, colls.Sum());
    for (int i = 0; i < colls.Count(); ++i) {
        lucky -= colls[i];
        if (lucky <= 0)
            return i;
    }
    // should never reach here
    return -1;
}

加权循环算法 https://dotnetfiddle.net/71Sft0

public class WRRScheduler
{
    // A list of node name/label -> weight
    List<Tuple<string, int>> nodes;
    int maxWeight;
    int step;

    int idx;
    int quantum;

    // for testing purpose
    public static void Main()
    {
        var colls = new List<Tuple<string, int>> {
            Tuple.Create("A", 5), Tuple.Create("B", 1),
            Tuple.Create("C", 7), Tuple.Create("D", 3)
        };
        var s = new WRRScheduler(colls);

        for (int i = 0; i < colls.Sum(e => e.Item2); ++i)
            Console.WriteLine("choose {0}", s.next());
    }

    public WRRScheduler(List<Tuple<string, int>> nodes) {
        this.nodes = nodes;

        this.maxWeight = nodes.Max(e => e.Item2);
        // use gcd as a optimization
        this.step = nodes.Select(e => e.Item2).Aggregate(gcd);

        this.idx = -1;
        this.quantum = 0;
    }

    string next() {
        while (true) {
            this.idx = (this.idx + 1) % this.nodes.Count;
            if (this.idx == 0) {
                // start a new round, decrement current quantum
                this.quantum -= this.step;
                if (this.quantum <= 0) {
                    this.quantum = this.maxWeight;
                }
            }

            // pick the node if its weight greater than current quantum
            if (this.nodes[this.idx].Item2 >= this.quantum) {
                return this.nodes[this.idx].Item1;
            }
        }
    }

    private static int gcd(int a, int b)
    {
        while (a != 0 && b != 0) {
            if (a > b)
                a %= b;
            else
                b %= a;
        }
        return a == 0 ? b : a;
    }
}

Random Weighted Select algorithm

// returns the index of the chosen one, note that the index starting with 0
static int randomWeightedSelect(List<int> colls) {
    int lucky = rand.Next(1, colls.Sum());
    for (int i = 0; i < colls.Count(); ++i) {
        lucky -= colls[i];
        if (lucky <= 0)
            return i;
    }
    // should never reach here
    return -1;
}

Weighted Round Robin Algorithm https://dotnetfiddle.net/71Sft0

public class WRRScheduler
{
    // A list of node name/label -> weight
    List<Tuple<string, int>> nodes;
    int maxWeight;
    int step;

    int idx;
    int quantum;

    // for testing purpose
    public static void Main()
    {
        var colls = new List<Tuple<string, int>> {
            Tuple.Create("A", 5), Tuple.Create("B", 1),
            Tuple.Create("C", 7), Tuple.Create("D", 3)
        };
        var s = new WRRScheduler(colls);

        for (int i = 0; i < colls.Sum(e => e.Item2); ++i)
            Console.WriteLine("choose {0}", s.next());
    }

    public WRRScheduler(List<Tuple<string, int>> nodes) {
        this.nodes = nodes;

        this.maxWeight = nodes.Max(e => e.Item2);
        // use gcd as a optimization
        this.step = nodes.Select(e => e.Item2).Aggregate(gcd);

        this.idx = -1;
        this.quantum = 0;
    }

    string next() {
        while (true) {
            this.idx = (this.idx + 1) % this.nodes.Count;
            if (this.idx == 0) {
                // start a new round, decrement current quantum
                this.quantum -= this.step;
                if (this.quantum <= 0) {
                    this.quantum = this.maxWeight;
                }
            }

            // pick the node if its weight greater than current quantum
            if (this.nodes[this.idx].Item2 >= this.quantum) {
                return this.nodes[this.idx].Item1;
            }
        }
    }

    private static int gcd(int a, int b)
    {
        while (a != 0 && b != 0) {
            if (a > b)
                a %= b;
            else
                b %= a;
        }
        return a == 0 ? b : a;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文