zoukankan      html  css  js  c++  java
  • 应用负载均衡之LVS(五):lvs和nginx的wrr加权调度算法规律分析

    返回LVS系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.html

    加权调度算法(wrr)是一种很常见的调度算法。它们按照权重比例进行调度,但实际调度选中的节点顺序可能和想象中并不一样。它们有各自的算法支持,但无论什么算法,对于a、b、c三个节点,如果它们的权重比例为a:b:c=x:y:z,在节点都健康的情况下,每一轮轮询过程中a总是被选中x次,b总是被选中y次,c总是被选中z次,只不过被选中的顺序可能因算法不同而不同,

    所以,本文主要介绍lvs和nginx的wrr算法是如何计算的。

    lvs的wrr调度算法

    1.加权调度算法公式

    首先,给一个LVS官方手册给的加权调度算法公式:

    假设有一组服务器S = {S0, S1, …, Sn-1},W(Si)表示服务器Si的权值,一个
    指示变量i表示上一次选择的服务器,指示变量cw表示当前调度的权值,max(S)
    表示集合S中所有服务器的最大权值,gcd(S)表示集合S中所有服务器权值的最大
    公约数。变量i初始化为-1,cw初始化为零。

    while (true) {
      i = (i + 1) mod n;
        if (i == 0) {
            cw = cw - gcd(S); 
            if (cw <= 0) {
                cw = max(S);
            if (cw == 0)
                return NULL;
            }
        } 
      if (W(Si) >= cw) 
        return Si;
    }
    

    比如,A、B、C三个后端的权重比是2:3:4,那么一个调度循环内的调度顺序是CBCABCABC。

    如果你不想从算法公式里找规律,那么看下面。

    2.加权调度通俗规律

    记住三个权重调度规则:
    1.先约分
    2.从最大权重开始调度
    3.同权重的后端,从前向后调度

    例如,三台后端A:B:C=2:3:4。这里没法约分。

    1. 调度C
      调度之后,比率变成A:B:C=2:3:3,B和C权重相同,从B开始调度
    2. 调度B
      调度之后,比率变成A:B:C=2:2:3,所以下次调度C
    3. 调度C
      调度之后,比率变成A:B:C=2:2:2,下次从A开始
      当权重全部调整到相同值时,就按照先后顺序不断循环,直到调度完所有权重
    4. 调度A,调度之后,比率变成A:B:C=1:2:2
    5. 调度B,调度之后,比率变成A:B:C=1:1:2
    6. 调度C,调度之后,比率变成A:B:C=1:1:1
    7. 调度A,调度之后,比率变成A:B:C=0:1:1
    8. 调度B,调度之后,比率变成A:B:C=0:0:1
    9. 调度C,调度之后,比率变成A:B:C=0:0:0
    10. 进入下一个调度循环,顺序是:CBCABCABC

    所以,每个调度循环的调度顺序为:CBCABCABC

    调度过程如下图:

    再给个示例,A:B:C:D=2:4:6:8

    首先约分,得到A:B:C:D=1:2:3:4

    1. 调度D
    2. 调度C
    3. 调度D
    4. 调度B
    5. 调度C
    6. 调度D
    7. 调度A
    8. 调度B
    9. 调度C
    10. 调度D

    所以,调度顺序是DCDBCDABCD。

    nginx的wrr调度算法

    以前nginx的wrr调度算法和lvs的算法类似,都是直接剃短高权重节点的权重值,最后趋于均衡。但这样的算法实际上对请求而言并不均衡,比如a:b:c = 5:1:1,调用的顺序将是aaaaabc、aaaaabc,a将被连续多次调用。

    后来nginx的wrr算法改进了,变得更复杂一些,但更趋于调度均衡。

    假设a:b:c=A:B:C,算法是这样的:

    1. 所有权重加总得到总权重(total):A+B+C=N
    2. 第一个请求进来,选择权重最大的。假设为a,于是选中A。选中之后,对选中的节点的权重减去总权重N,于是现在的比例是a:b:c=A-N:B:C
    3. 第二个请求进入,将比如全部加上原始比例(eff_weight),得到(A-N+A):(B+B):(C+C),然后选中最大的权重节点,假如选中B。选中之后,对选中的节点的权重减去总权重N,于是比例变为(2A-N):(2B-N):2C
    4. 之后每个请求进来,都首先加上原始比例,然后选择权重最大的,并对最大的权重值减去总权重N。
    5. 每一轮询的最后一次调度,都会使被选中的节点权重变为N,其它权重变为0,减去总权重之后全部变成0,使得下一轮轮询调度开始,重新回到原始比例。

    例如,a:b:c=4:3:2的调度过程为:总权重为4+3+2=9

    1. 第1个请求,a权重最大,选中a
      • 选中之后,比例变为a:b:c=-5:3:2
    2. 第2个请求,加上原始比例,得到a:b:c=-1:6:4,选中b
      • 选中之后,比例变为a:b:c=-1:-3:4
    3. 第3个请求,加上原始比例,得到a:b:c=3:0:6,选中c
      • 选中之后,比例变为a:b:c=3:0:-3
    4. 第4个请求,加上原始比例,得到a:b:c=7:3:-1,选中a
      • 选中之后,比例变为a:b:c=-2:3:-1
    5. 第5个请求,加上原始比例,得到a:b:c=2:6:1,选中b
      • 选中之后,比例变为a:b:c=2:-3:1
    6. 第6个请求,加上原始比例,得到a:b:c=6:0:3,选中a
      • 选中之后,比例变为a:b:c=-3:0:3
    7. 第7个请求,加上原始比例,得到a:b:c=1:3:5,选中c
      • 选中之后,比例变为a:b:c=1:3:-4
    8. 第8个请求,加上原始比例,得到a:b:c=5:6:-2,选中b
      • 选中之后,比例变为a:b:c=5:-3:-2
    9. 第9个请求,加上原始比例,得到a:b:c=9:0:0,选中a
      • 选中之后,比例变为a:b:c=0:0:0

    一轮循环完成,调度的顺序是a b c a b a c b a,这轮循环完成之后,它们的比例变为0:0:0,下一个请求到来,加上原始权重后回到原比例4:3:2

    如果是两后端节点,它们的比例为3:1,它们的调度顺序将是aaba aaba aaba...

  • 相关阅读:
    不规范的json文档 转化成 java 对象的处理
    财经接口
    Back-off pulling image "registry.access.redhat.com/rhel7/pod-infrastructure:latest
    VMware Workstation 14 Pro永久激活密钥
    Angular2入门:TypeScript的装饰器
    Angular2入门:TypeScript的模块
    Angular2入门:TypeScript的类
    51nod“省选”模测第二场 B 异或约数和(数论分块)
    51nod1238 最小公倍数之和 V3(莫比乌斯反演)
    cf1139D. Steps to One(dp)
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/9490629.html
Copyright © 2011-2022 走看看