惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security @ Cisco Blogs
P
Privacy & Cybersecurity Law Blog
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Project Zero
Project Zero
C
CERT Recently Published Vulnerability Notes
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cisco Blogs
博客园 - 司徒正美
L
LINUX DO - 热门话题
D
Docker
M
MIT News - Artificial intelligence
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
Cisco Talos Blog
Cisco Talos Blog
Jina AI
Jina AI
Last Week in AI
Last Week in AI
Security Latest
Security Latest
The Hacker News
The Hacker News
L
Lohrmann on Cybersecurity
Y
Y Combinator Blog
A
Arctic Wolf
小众软件
小众软件
T
Threat Research - Cisco Blogs
Know Your Adversary
Know Your Adversary
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
I
InfoQ
腾讯CDC
Google DeepMind News
Google DeepMind News
B
Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 叶小钗
I
Intezer
NISL@THU
NISL@THU
A
About on SuperTechFans
爱范儿
爱范儿
C
Cybersecurity and Infrastructure Security Agency CISA
D
Darknet – Hacking Tools, Hacker News & Cyber Security
G
Google Developers Blog
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Cyberwarzone
Cyberwarzone
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
Latest news
Latest news

Claude's Blog

浅谈 npm 依赖治理 记录 Got(Node.js) 代理 HTTP 请求的坑 如何管理桌面窗口 SSR 页面 CDN 缓存实践 从 is-promise 事件我们可以学到什么 分享一个 npm dist-tag 的冷知识 从 Vimium 到 qutebrowser Verdaccio 性能优化:单机 Cluster 让 npm install 不使用缓存的方法 Verdaccio 性能优化:代理分流 Verdaccio 性能优化:上游路径转发 CSAPP DataLab 题解 不靠谱的 Egg.js 框架开发指南 如何解决 Debian 系 Elastic apm-server 7.x 启动失败 Hexo NexT 主题升级 7.4 From Journeyman to Master Mac 上移除 EasyConnect 常驻后台进程 记一次 Node.js 进程挂起的 BUG 追踪 警惕 Travis CI 的 npm 缓存
Nginx SWRR 算法解读
Post author: Claude Ray · 2019-08-10 · via Claude's Blog

Smooth Weighted Round-Robin (SWRR) 是 nginx 默认的加权负载均衡算法,它的重要特点是平滑,避免低权重的节点长时间处于空闲状态,因此被称为平滑加权轮询。

该算法来自 nginx 的一次 commit:Upstream: smooth weighted round-robin balancing

在阅读之前,你应该已经了解过 nginx 的几种负载均衡算法,并阅读了 SWRR 的实现。

介绍此算法的文章有很多,但用数学角度给出证明过程的较少,尽管并不复杂。这里把自己的思路分享一下,为了便于理解,只考虑算法核心的 current_weight,忽略受异常波动影响的 effective_weight。

更新说明

在写下博客之前,我还没有翻到其他靠谱的证明过程,就草草记录了自己粗鄙的思路。可发布文章一年之后,再来回顾的我不禁汗颜,为了照顾读者(更未来的自己),参考 nginx平滑的基于权重轮询算法分析 重新梳理了文章脉络。

以至于现在的内容更像是他人博客的学习笔记,和初版大不相同。这让患有原创洁癖的我深感羞愧,之后的自己务必用更数学的风格去做解析。

算法描述

由于所有节点都有原始权重和当前权重,为了方便区分,我们称当前权重为“状态”。

节点的初始状态均为 0,每开始一轮新的选择,先为各个节点加上其原始权重大小的值,然后选出权重最大的节点,将其值减去所有节点的权重和,最后,该节点作为命中节点返回。

接下来是官方的示例,对于权重占比 { 5, 1, 1 } 的 A, B, C 三个节点,每轮节点的选择和状态的变换如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| Round |  A |  B |  C | Selected Node |
|-------|----|----|----|---------------|
| | 0 | 0 | 0 | |
|-------|----|----|----|---------------|
| 1 | 5 | 1 | 1 | A |
| | -2 | 1 | 1 | |
|-------|----|----|----|---------------|
| 2 | 3 | 2 | 2 | A |
| | -4 | 2 | 2 | |
|-------|----|----|----|---------------|
| 3 | 1 | 3 | 3 | B |
| | 1 | -4 | 3 | |
|-------|----|----|----|---------------|
| 4 | 6 | -3 | 4 | A |
| | -1 | -3 | 4 | |
|-------|----|----|----|---------------|
| 5 | 4 | -2 | 5 | C |
| | 4 | -2 | -2 | |
|-------|----|----|----|---------------|
| 6 | 9 | -1 | -1 | A |
| | 2 | -1 | -1 | |
|-------|----|----|----|---------------|
| 7 | 7 | 0 | 0 | A |
| | 0 | 0 | 0 | |

证明思路

假设有三个服务器节点 A B C,它们的权重分别为 a、b、c 并保持不变,W 表示所有服务器节点权重的总和,即 W = a + b + c。

根据 SWRR 算法,每台服务器的初始权重均为 0。

A B C
0 0 0

也可以用等式表达当前的权重(状态)之和

1
Sum = 0 + 0 + 0 = 0

每次开始选择,各节点的状态会增加对应权重的大小。从中选择 CW 最大的节点,并将其值减去 W。

首先,所有节点加权,不妨设 A 为权重最大的节点,经过第一轮变换之后

A B C
a - W b c

此时,节点的状态和仍然为 0

1
2
3
Sum = (a - W) + b + c
= (a - a - b - c) + b + c
= 0

综上,每一轮选择都是将总资源根据权重分配给各自节,再由权重最大的节点一次性消耗掉。依此类推,无论第几次选择,他们的和恒等于零。


假设 A 已经被选择了 a 轮 (a < W),即将开始第 n 轮选择(a < n < W),那么 A 节点的状态为

1
n * a - a * W = a * (n - W) < 0

由于状态总和恒为 0,而 A 节点状态小于 0 的时候一定不会被选中,因此 A 最多只能被选择 a 轮。同理,其他每个节点也最多只能被选择等同于节点权重的次数。


最后证明算法的平滑性,即 A 节点不会连续被选择 a 次。

不妨设 A 节点已经被连续选择了 a - 1 次,那么当前 A 节点的状态为

1
(a - 1) * a - (a - 1) * W = (a - 1) * (a - W) < 0

同上一条证明,由于状态总和恒为 0,而 A 节点状态小于 0 的时候一定不会被选中,因此 A 最多只能被连续选中 a - 1 轮。即每个节点也不会被连续选择,平滑性得证。