如何数学上证明Nginx平滑权重负载均衡算法?

时间:2018-12-27 15:08:46

标签: java algorithm nginx math

请参阅Nginx提交的代码:https://github.com/phusion/nginx/commit/27e94984486058d73157038f7950a0a36ecc6e35

class Server {
    String name;
    int weight;
    int curWeight;

    Server(String name, int weight) {
        super();
        this.name = name;
        this.weight = weight;
    }

    void add(int weight) {
        curWeight += weight;
    }

    void subtract(int weight) {
        curWeight -= weight;
    }

    @Override
    public String toString() {
        return String.format("%s=%2d", name, curWeight);
    }

    public String getName() {
        return name;
    }

    public int getWeight() {
        return weight;
    }

    public int getCurWeight() {
        return curWeight;
    }

}

class LoadBalance {
    private int matched = -1;
    private Server[] servers;

    LoadBalance(Server... servers) {
        super();
        this.servers = servers;
    }

    Server get() {
        int totalWeight = 0;
        for (int i = 0, len = servers.length; i < len; i++) {
            servers[i].add(servers[i].getWeight());
            totalWeight += servers[i].getCurWeight();
            if (matched == -1 || servers[matched].getCurWeight() < servers[i].getCurWeight()) {
                matched = i;
            }
         }

        System.out.println(Arrays.toString(servers) + " " + servers[matched].getName() + " selected");
        servers[matched].subtract(totalWeight);
        System.out.println(Arrays.toString(servers));

        return servers[matched];
    }

}

public class LoadBalanceTest {

    public static void main(String[] args) {
        LoadBalance loadBalance = new LoadBalance(new Server("a", 5), new Server("b", 1), new Server("c", 1));
        for (int i = 0; i < 10; i++) {
            loadBalance.get();
        }
    }

} 

当输入节点(a,b,c)的权重比为(5,1,1)时,输出结果如下:

[a= 5, b= 1, c= 1] a selected
[a=-2, b= 1, c= 1]
[a= 3, b= 2, c= 2] a selected
[a=-4, b= 2, c= 2]
[a= 1, b= 3, c= 3] b selected
[a= 1, b=-4, c= 3]
[a= 6, b=-3, c= 4] a selected
[a=-1, b=-3, c= 4]
[a= 4, b=-2, c= 5] c selected
[a= 4, b=-2, c=-2]
[a= 9, b=-1, c=-1] a selected
[a= 2, b=-1, c=-1]
[a= 7, b= 0, c= 0] a selected
[a= 0, b= 0, c= 0]
[a= 5, b= 1, c= 1] a selected
[a=-2, b= 1, c= 1]
[a= 3, b= 2, c= 2] a selected
[a=-4, b= 2, c= 2]
[a= 1, b= 3, c= 3] b selected
[a= 1, b=-4, c= 3]

对于每7次执行(权重总和),权重重置为0,并且服务分配时间的比例也满足权重比例,并且分布也相对均匀a,a,b,a,c,a和一个。

但是我不明白为什么会这样。如何在数学上证明算法?

1 个答案:

答案 0 :(得分:0)

尚不清楚您要证明的属性到底是什么。关于重量的正确性不难证明。

假设我们有权重为Wi的整数权重S

要求#1::将连续S次选择i个服务器上连续Wi个连续选择。

这是证明的草图。声明#1来自声明#2:,在任何情况下都不能选择负当前权重(CWi)的服务器。依次为索赔3 :在每一步中,所有当前权重之和为0。

声明#3显然是正确的:在算法的每个步骤中,我们将每个Wi加到当前权重CWi上,然后从所选的权重中减去S。因此我们加减S。因此总和与第一步之前相同,即0。

如果总和始终为0,则意味着如果存在负的当前权重,则必须存在正的当前权重。显然,任何一个正的当前权重比一个负的当前权重是更好的选择,因此我们已经证明了索赔2。

返回至索赔#1:假设已选择iNi的某些服务器,然后选择Wi以上。让我们看看上一次进行这样的选择。假设它是某个步骤编号j0 < j < S,严格来说,您还需要在第一步j=0时考虑选择的情况,但是很明显,每个服务器都具有非-零权重将至少选择一次,这样第一步就不会发生“溢出”。在第j步,其当前权重CWi = j*Wi - (Ni-1)*S。自Ni > Wi起,它的意思是Ni-1 >= Wi;和j < S。因此,j*Wi < (Ni-1)*SCWi < 0。而且我们知道,永远不会选择负当前权重的服务器。矛盾。

现在假设选择第i个服务器的次数少于Wi。由于服务器选择的总数是固定的,因此其他一些j-服务器被选择的次数比Wj多,我们已经知道这不可能发生。这样就完成了我们对索赔1的证明。

至于“ 分布也相对均匀”部分,它不是形式化的陈述,因此无法得到证明。