返回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...

应用负载均衡之LVS(五):lvs和nginx的wrr加权调度算法规律分析的更多相关文章

  1. 架构设计:负载均衡层设计方案(3)——Nginx进阶

    版权声明:欢迎转载,但是看在我辛勤劳动的份上,请注明来源:http://blog.csdn.net/yinwenjie(未经允许严禁用于商业用途!) 目录(?)[-] Nginx继续进阶 1gzip ...

  2. 架构设计:负载均衡层设计方案(6)——Nginx + Keepalived构建高可用的负载层

    1.概述 前两遍文章中,我们一直在说后文要介绍Nginx + Keepalived的搭建方式.这篇文章开始,我们就来兑现前文的承诺,后续的两篇文章我们将介绍Nginx + Keepalived和 LV ...

  3. Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx)

    Linux 集群概念 , wsgi , Nginx负载均衡实验 , 部署CRM(Django+uwsgi+nginx), 部署学城项目(vue+uwsgi+nginx) 一丶集群和Nginx反向代理 ...

  4. LVS负载均衡+动静分离+高可用(nginx+tomcat+keepalived)

    文章目录 [隐藏] 一.环境介绍 二.环境安装 1.安装JDK 2.两台服务器安装tomcat 3.nginx安装 4.keepalive安装 三.负载均衡 四.动静分离 五.keepalive高可用 ...

  5. 亚洲唯一,阿里云SLB位列Gartner全球网络负载均衡市场前五

    近日,Gartner发布了最新的全球企业级网络设备市场份额报告“Market Share: Enterprise Network Equipment by Market Segment, Worldw ...

  6. 生产环境使用nginx做负载均衡配置的五种策略

    nginx的upstream目前支持5种方式的分配1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight指定轮询几率,weight和访 ...

  7. 架构设计:负载均衡层设计方案(2)——Nginx安装

    来源:http://blog.csdn.net/yinwenjie(未经允许严禁用于商业用途!) 目录(?)[-] Nginx重要算法介绍 1一致性Hash算法 2轮询与加权轮询 Nginx的安装 1 ...

  8. asp.net core 负载均衡集群搭建(centos7+nginx+supervisor+kestrel)

    概述 本文目的是搭建三台asp.net core 集群, 并配上 nginx做负载均衡   首先准备要运行的源码 http://pan.baidu.com/s/1c20x0bA 准备三台服务器(或则虚 ...

  9. 负载均衡集群之LVS的DR模型详解(Diretor Routing)

    LVS的默认模型:默认模型DR DR模型原理图--> 在讲DR模型要点之前,需要了解网络的相关知识: 接收的报文拆解顺序:帧(MAC)-->数据包(IP)-->数据报文(port) ...

随机推荐

  1. EmEditor注册码

    Emeditor 是一款非常好用的文本编辑器 Emeditor 注册码 姓 名:ttrar.com 序 列 号:DKAZQ-R9TYP-5SM2A-9Z8KD-3E2RK 姓 名:whyida 序 列 ...

  2. Runnable与Callable区别

    相同点: 两者都是接口:(废话) 两者都可用来编写多线程程序: 两者都需要调用Thread.start()启动线程: 不同点: 两者最大的不同点是:实现Callable接口的任务线程能返回执行结果:而 ...

  3. 【Golang】如何统一处理HTTP请求中的异常捕获

    最近写GOLANG项目,不使用框架,路由选择httprouter 现在想实现一个需求:在不修改httprouter源码的前提下,对所有注册的路由handle进行异常捕获. 大家都知道golang使用p ...

  4. 《NoSQL精粹》读后感

    <NoSQL精粹>作者Pramod J. Sadalaga.Martin Flower著,译者爱飞翔. 本书以关系型数据库开头,讲解了关系型数据库的优缺点,然后引入了NoSQL数据库,并且 ...

  5. U-Boot Makefile分析(4)具体子Makefile的分析

    前面分析的都是多数Makefile要读入的文件,这次我们以drivers/mtd/nand/Makefile为例,分析一个具体的子Makefile是如何工作的. 子Makefile的结构是固定的: i ...

  6. 【repost】javascript callback

    在javascript中回调函数非常重要,它们几乎无处不在.像其他更加传统的编程语言都有回调函数概念,但是非常奇怪的是,完完整整谈论回调函数的在线教程比较少,倒是有一堆关于call()和apply() ...

  7. PMP:10.项目采购管理

    内容中包含 base64string 图片造成字符过多,拒绝显示

  8. 复习java基础

    十进制转换成二进制:     方法:整除法,计数方式从右往左,二进制中非0即1.例子如下: 计数方式是从右往左进行,然后填写数字的顺序是余数优先 二进制转换成十进制: 方法:乘二法,例如二进制数字为: ...

  9. js怎么实现继承?

    3. js怎么实现继承? 1. 使用原型prototype 这个问题其实之前总结过了……但是面试时候有点忘……主要思想是记得的,但是不会写,还是基础太不牢靠,写的太少了.一开始因为不知道怎么能继承父类 ...

  10. CentOS7编译安装MySQL5.7.24

    目录 安装依赖 安装boost 编译安装MySQL 配置 登录MySQL,修改密码 安装依赖 (1)cmake是新版MySQL的编译工具 sudo yum install gcc gcc-c++ pc ...