LVS就像一个交通警察,他站在所有请求的面前,决定 把每一个请求发给后台哪台服务器去处理。它用来做决定的13种调度算法可以分成两大类:
静态算法:仅根据算法本身进行调度,不考虑RS的负载情况。
用最通俗易懂的话来解释就是,静态算法就像是"死脑筋",不管服务器忙不忙,都按照固定规则分发。
动态算法:主要根据每台RS当前的负载状态以及调度算法进行调度Overhead=value较小的RS将调度。
简单来说动态算法就像是"机灵鬼",会看服务器当前谁更闲,再把活派给谁。
一、静态算法:按照固定规矩办事
1.RR(轮询),roundrobin,RS分别被调度,当RS配置有差别的时候不推荐。
原理解释:轮询就是按顺序,一个接一个地轮流分配,就像食堂打饭,窗口1.2.3.1.2.3.......轮流来
2.WRR(加权轮询),Weighted RR,加权轮询根据RS的配置进行加权调度,性能差的RS被调度的次数少。
原理解释:加权轮询按权重比例分配,性能好的服务器多分点,性能好的窗口开两个打饭通道,普通窗口开一个,通道多的自然打饭快。
3.SH(源地址散列),Source Hashing,实现session sticky,源地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定。
原理解释:SH根据来源地址(比如你的电脑IP)计算,始终分配给同一个服务器,就好比你是一个vip客户,无论办什么业务,都带你去找同一个专属客户经理。
计算逻辑:不是用公式比大小,而是通过一个数学函数,把IP地址算成一个"门牌号",然后去一张事先准备好的"地址-服务器"对照表里找对应的服务器。
核心三步走
-
算"钥匙":把IP地址(一串数字)通过哈希函数,算出一个整数(哈希值)。
-
找"门牌号":用哈希值对哈希表的大小(桶的数量)取余数,得到桶的索引。
-
取"服务器":去哈希表的这个索引桶里,取出对应的真实服务器IP。
4.DH(目标地址散列),Destination Hashing,目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商。
原理解释:DH根据目标IP地址(比如请求的网站IP)计算,始终分配给同一台服务器,就如去特定楼层办业务,永远都去指定的那个柜台。
计算逻辑:不是用公式比大小,而是通过一个数学函数,把IP地址算成一个"门牌号",然后去一张事先准备好的"地址-服务器"对照表里找对应的服务器。
核心三步走
-
算"钥匙":把IP地址(一串数字)通过哈希函数,算出一个整数(哈希值)。
-
找"门牌号":用哈希值对哈希表的大小(桶的数量)取余数,得到桶的索引。
-
取"服务器":去哈希表的这个索引桶里,取出对应的真实服务器IP。
具体例子
假设我们有 3台后端服务器:
-
S1 (192.168.1.10)
-
S2 (192.168.1.20)
-
S3 (192.168.1.30)
LVS内部维护了一张 哈希表 ,表里有 4个桶(索引为 0, 1, 2, 3),事先把服务器分配到了不同的桶里(这只是个示例分配):
| 桶索引 | 分配的服务器 |
|---|---|
| 0 | S1 |
| 1 | S2 |
| 2 | S3 |
| 3 | S1 |
场景:客户端 192.168.1.100 第一次访问
第1步:计算哈希值(算"钥匙")
把点分十进制的IP转成一个整数。
192.168.1.100 对应的整数是:192 * 256^3 + 168 * 256^2 + 1 * 256 + 100 = 3232235876
注意 :LVS内核实际会用更复杂的算法(如 jhash)让结果分布更均匀。
第2步:找门牌号(取余数)
拿整数除以哈希表的总桶数(这里是4),取余数。
3232235876 % 4 = 0
得到的结果是 0 ,也就是 0号桶。
第3步:查表取服务器
去哈希表里看 0号桶 对应的是谁?
查表得知是 S1 。
✅ 结论 :这个请求被分配给 S1。
场景:同一个客户端 192.168.1.100 再次访问
因为同一个IP算出的整数永远不变,3232235876 % 4 永远等于 0 。
所以它永远被查表分配到 S1 。
这就是为什么**源地址散列(SH)**能保证"同一个客户永远分配给同一台服务器"(会话保持)。
⚙️ 如果有4台服务器,哈希表大小怎么定?
你可能会发现,服务器数量(3台) 和 哈希表的桶数(4个) 不一定相等。为什么要这么设计?
-
增加灵活性 :表大小通常设置成2的幂次方(如 4, 8, 16, 32...),这样计算时可以用按位与(&) 代替取余(%),CPU运算速度会快很多。
-
映射关系 :LVS会通过一个映射数组 ,把多个桶指向同一台服务器(比如上面的例子,0号和3号都指向S1)。这相当于给性能强的服务器多分配几个桶,变相实现了加权。
🔧 当服务器变化时怎么"算"?
这是哈希算法最需要注意的地方。
-
新增一台服务器 S4 :LVS会重建哈希表 (重新计算所有IP的桶位置)。比如原来在0号桶的客户端,扩容后可能被分到3号桶,导致它被切换到新服务器 ,这就叫哈希漂移。
-
解决方法 :LVS采用一致性哈希 的思路来缓解,但原理核心不变------查表决定结果,表变了,结果就变了。
🆚 DH 和 SH 的区别在哪?
计算过程一模一样 ,唯一的区别是拿谁的IP去算:
-
SH(源地址散列) :拿 客户端的IP 去算,结果是"哪个客户端来,固定找哪台服务器"。
-
DH(目标地址散列) :拿 请求的目标IP(比如访问的网站VIP)去算,结果是"访问哪个目标地址,固定找哪台服务器"(常用于缓存集群)。
二、、动态算法:看情况灵活分配
1.LC(最少链接),least connections,适用于长连接应用Overhead(负载值)=activeconns(活动链接数)x256+inactiveconns(非活动链接数)
原理解释:谁当前处理的请求少,就发给谁,就像哪个柜台排队的人少就去哪个柜台结账。
计算逻辑(谁胜出):值最小的服务器胜出。
2.WLC(权重最少链接),默认调度方法Overhead=(activeconns x 256+inactiveconns)/weight
原理解释:在"最少连接"的基础上,考虑服务器性能权重,就像一个老员工结账飞快(权重大),虽然它后面排了3个人,但可能比新员工后面排一个人处理的更快,所以还是优先考虑他
计算逻辑(谁胜出):值最小的服务器胜出。
举例:
假设有三台服务器A、B、C,权重分别是1、2、3。目前它们都有1个活动连接,没有非活动连接。
-
WLC算法 计算开销:
-
A:
(1×256 + 0) / 1 = 256 -
B:
(1×256 + 0) / 2 = 128 -
C:
(1×256 + 0) / 3 ≈ 85.3 -
结果:C的开销最小,新请求发给C。
-
3.SED(最短期望延迟),Shortest Expection Delay,初始连接高权重优先,Overhead=(activeconns+1+inactiveconns)x256/weight,但是,当node1的权重为1,node2的权重为10,经过运算前几次的调度都会被node2承接
原理解释:基于WLC的改进,更倾向于性能好的服务器,同样是排队,会优先把一个新来的客户引导给业务能力最强、预期等待时间最短的哪个员工。
计算逻辑(谁胜出):值最小的服务器胜出。
假设有三台服务器A、B、C,权重分别是1、2、3。目前它们都有1个活动连接,没有非活动连接。
-
SED算法 计算开销:
-
A:
(1 + 1) × 256 / 1 = 512 -
B:
(1 + 1) × 256 / 2 = 256 -
C:
(1 + 1) × 256 / 3 ≈ 170.6 -
结果 :同样是C的开销最小。关键区别 在于,SED通过
+1让高权重服务器在初始时优势更明显。
-
4.NQ(最少队列),Never Queue,第一轮均匀分配,后续SED。
原理解释:SED的插队版。如果某台服务器完全空闲(连接数为0),就直接把请求塞给他,不用计算。就像看到有个柜台完全没人排队,立马把新客户引过去,不用思考。
计算逻辑(谁胜出):如果没有空闲服务器,则退回到SED算法的规则。
5.LBLC(基于局部性的最少连接),Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理。
原理解释:为缓存服务器设计,尽量把相同目标IP的请求发给同一台缓存了该数据的服务器。就像你每次都去同一家网吧(缓存服务器)上网,老板知道你喜欢坐哪台机器,就尽量把你往哪台机器带。
6.LBLCR(带复制的基于局部性最少连接)LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS。
原理解释:LBLC的升级版。当一个缓存服务器太忙时,会把"热门数据"复制到其他较闲的服务器上,大家一起分担。就比如那台机器太火了,老板干脆在另外几台空闲机器上也装好你喜欢的游戏,然后把你分配到那些机器上。
7.FO(故障转移),Weighed Fai Over.常用做灰度发布,在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_FOCERLOAD标志)的且权重最高的真实服务器进行调度,当服务器承接大量链接,我们可以对此服务器进行过载标记,那么vs调度器就不会把链接调度到有过载标记的主机中。
原理解释:主备模式。主要把请求发给优先级最高的服务器,只有它挂了,才发给次优先级的。就像领导先找部门经理,经理不在才找副经理。
8.OVF(加权故障转移),Overflow-connection,基于真实服务器的活=活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器上,直到其活动的链接数量超过权重值,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件
(1)未过载(IP_VS_DEST_FOCERLOAD)
(2)真实服务器当前的活动连接数量小于其权重值
(3)其权重值不为0
原理解释:FO的升级版,会结合服务器的负载和权重来动态判断谁是最佳选择,也就是说经理在忙,但副经理很闲,并且能力足够,就有可能直接找副经理了。
三、12种调度算法对比
| 算法名称 | 类别 | 核心原理 | 主要优点 | 主要缺点 | 适用场景 |
|---|---|---|---|---|---|
| 轮询 (RR) | 静态 | 按顺序轮流分配,人人有份。 | 实现最简单,无需记录连接状态,开销极小。 | 无视服务器性能差异,可能导致性能差的服务器过载。 | 后端服务器性能完全一致 ,且每个请求负载都差不多的场景。 |
| 加权轮询 (WRR) | 静态 | 按权重比例分配,权重越高,分到的请求越多。 | 解决了RR的缺点,能根据服务器性能进行差异化分配。 | 需要手动配置权重,无法根据服务器实时负载动态调整。 | 后端服务器性能有差异,但请求处理时间相对固定的场景。 |
| 源地址散列 (SH) | 静态 | 根据客户端IP计算,同一客户始终分配给同一台服务器。 | 可实现会话保持(Session Sticky),解决登录状态等问题。 | 可能导致负载不均,若某IP请求频繁,对应服务器可能过载。 | 强需要会话保持的应用,如需要维持用户登录状态的网站。 |
| 目标地址散列 (DH) | 静态 | 根据目标IP计算,同一目标IP始终分配给同一台服务器。 | 能将访问同一目标地址的请求集中 ,提高缓存命中率。 | 若服务器故障,其负责的所有缓存会失效,需重新建立。 | 缓存服务器集群,如反向代理缓存。 |
| 最少连接 (LC) | 动态 | 谁当前处理的连接数最少,就发给谁。 | 动态感知服务器负载,能更均匀地分配请求。 | 无视服务器性能差异,性能强的服务器无法发挥全部能力。 | 请求处理时间长短不一的长连接应用,如数据库、WebSocket等。 |
| 加权最少连接 (WLC) | 动态 | 结合权重和连接数计算负载值,值最小者胜出。 | 兼顾性能与实时负载 ,是最通用、最推荐的动态算法。 | 计算开销比静态算法略高。 | 大多数通用业务场景 ,尤其是后端服务器性能与负载均存在差异时。 |
| 最短期望延迟 (SED) | 动态 | WLC的改进版,通过+1给新服务器一个机会。 | 解决了WLC中新服务器(连接数为0)会一直被优先分配的问题。 | 理解起来比WLC复杂一点。 | 希望更智能地初始化分配,避免新服务器刚上线就涌入大量请求的场景。 |
| 最少队列 (NQ) | 动态 | 第一轮均匀分配,后续退回到SED算法。 | 解决了SED在刚开始时可能分配不均的问题。 | 实现略复杂,应用不如WLC广泛。 | 对请求分配的初始公平性有较高要求的场景。 |
| 基于局部性的最少连接 (LBLC) | 动态 | DH的升级版,优先分配给缓存了目标数据的服务器,若它太忙则按LC分配。 | 动态地兼顾了缓存命中率和服务器负载。 | 实现复杂,维护成本高。 | 缓存服务器集群 ,且缓存数据访问有局部性(如热门网站)。 |
| 带复制的基于局部性最少连接 (LBLCR) | 动态 | LBLC的升级版,允许将热门数据复制到多台服务器。 | 解决了LBLC中热门目标地址导致单台服务器过载的问题。 | 实现最复杂,数据一致性维护成本高。 | 大型缓存服务器集群 ,存在极热门的目标地址,单台服务器无法承载。 |
| 故障转移 (FO) | 动态 | 主备模式,优先分配给最高优先级的服务器。 | 实现简单,逻辑清晰。 | 资源利用率低,备机长期空闲。 | 对高可用性 要求极高,可接受一定资源浪费的主备容灾场景。 |
| 加权故障转移 (OVF) | 动态 | FO的升级版,结合权重和负载动态选择最优服务器。 | 比FO更灵活,能提升资源利用率。 | 实现比FO复杂。 | 需要主备切换 ,但又希望备机也能分担部分流量的场景。 |
四、总结与选型建议
选型时可以记住下面这几个核心原则:
-
配置都一样,请求也均匀?选
RR(轮询):简单、快速、够用。 -
服务器性能有高低?选
WRR(加权轮询)或WLC(加权最少连接):前者简单,后者更动态智能。 -
请求处理时间长短不一?选动态算法 :
LC(最少连接)或WLC(加权最少连接)。 -
需要"粘住"用户?选
SH(源地址散列):确保用户始终在同一台服务器上。 -
搭建的是缓存集群?选
DH、LBLC或LBLCR。 -
想要最通用、最稳妥的选择?选
WLC(加权最少连接) :它是LVS的默认算法,平衡了性能和负载,适用性最广。