衣从零打造算法题刷题助手:Agent搭建保姆级攻略e
这种方法的优点是实现简单,计算复杂度低(O(n)),但缺点是分配不够平滑,可能导致某些服务器短时间内接收大量请求。每次请求前,大家都获得与能力相符的积分,积分最高者获得处理机会,但需要扣除"入场费"(总权重)。A:5-10=-5,?算法将[0, T-1]的整数区间按权重比例划分为n个子区间,每个子区间的长度等于对应服务器的权重。同样配置:ServerA(5), ServerB(3), Server
诿迸蹲航一、非平滑权重轮询:老实人的直球对决 ?
1.1 算法原理:排排坐,分果果
非平滑权重轮询算法(又称静态权重轮询)的核心思想是基于权重比例进行确定性分配。算法维护一个全局计数器,通过对总权重取模来确定当前请求应该分配给哪个服务器。
详细实现原理:
初始化阶段:计算所有服务器权重的总和(totalWeight)
选择阶段:
维护一个原子计数器(currentIndex),确保线程安全
每次请求时,计数器递增并对总权重取模:index = (currentIndex + 1) % totalWeight
遍历服务器列表,用当前索引值依次减去每个服务器的权重
当剩余值小于某个服务器的权重时,选择该服务器
数学表达:
设服务器权重数组为 W = [w?, w?, ..., w?],总权重 T = Σw?
对于第k个请求,选择满足以下条件的服务器i:
Σ??1w? ≤ (k mod T) < Σ?w?,其中 j=1 to i
1.2 数学依据:区间映射理论 ??
严格的数学理论:
非平滑权重轮询基于数论中的模运算和区间划分原理。算法将[0, T-1]的整数区间按权重比例划分为n个子区间,每个子区间的长度等于对应服务器的权重。
数学上,可以表示为:
服务器i的分配区间为 [S?, S? + w?),其中 S? = Σ??1w? (j=1 to i-1)
对于请求序列号k,计算 m = k mod T
选择满足 m ∈ [S?, S? + w?) 的服务器i
通俗解释:
想象有一个长度为总权重的"轮盘赌",每个服务器占据与其权重成比例的扇形区域。每次请求就像旋转轮盘,指针停在哪个区域就选择对应的服务器。这种方法的优点是实现简单,计算复杂度低(O(n)),但缺点是分配不够平滑,可能导致某些服务器短时间内接收大量请求。
1.3 代码实现深度解析 ??
public Server getNextServer() {
// 使用原子操作确保线程安全,避免并发问题
int index = currentIndex.updateAndGet(i -> (i + 1) % totalWeight);
// 线性搜索找到对应的服务器
for (Server server : servers) {
if (index < server.getWeight()) {
return server; // 找到目标服务器
}
index -= server.getWeight(); // 调整索引,继续寻找
}
return servers.get(0); // 安全回退
}
代码分析:
AtomicInteger 确保多线程环境下的线程安全
取模运算 % totalWeight 将索引限制在 [0, totalWeight-1] 范围内
线性搜索的时间复杂度为 O(n),对于服务器数量不多的情况效率可接受
1.4 执行过程详细图示 ???
假设有三台服务器:
?? ServerA: 权重 5
?? ServerB: 权重 3
?? ServerC: 权重 2
总权重 = 10
详细的分配过程:
请求 当前索引 计算过程 选中服务器 分配模式
1 0 0 < 5? ? ?? ServerA A
2 1 1 < 5? ? ?? ServerA A
3 2 2 < 5? ? ?? ServerA A
4 3 3 < 5? ? ?? ServerA A
5 4 4 < 5? ? ?? ServerA A
6 5 5 < 5? ? → 5-5=0; 0 < 3? ? ?? ServerB B
7 6 6 < 5? ? → 6-5=1; 1 < 3? ? ?? ServerB B
8 7 7 < 5? ? → 7-5=2; 2 < 3? ? ?? ServerB B
9 8 8 < 5? ? → 8-5=3; 3 < 3? ? → 3-3=0; 0 < 2? ? ?? ServerC C
10 9 9 < 5? ? → 9-5=4; 4 < 3? ? → 4-3=1; 1 < 2? ? ?? ServerC C
模式分析:
分配序列为:A-A-A-A-A-B-B-B-C-C
这种分配明显不平滑,ServerA连续处理5个请求,然后ServerB处理3个,最后ServerC处理2个。
二、平滑权重轮询:情商满分的分配大师 ??
2.1 算法原理:动态权重调整机制
平滑权重轮询算法通过引入动态权重概念来解决非平滑算法的问题。每个服务器有两个权重值:
固定权重(weight):表示服务器的处理能力
当前权重(currentWeight):动态值,在运行时调整
详细实现原理:
初始化阶段:所有服务器的当前权重设为0
选择阶段:
每次请求前,所有服务器的当前权重增加其固定权重
选择当前权重最大的服务器
被选中服务器的当前权重减去总权重
重复此过程
数学本质:
这实际上是一种贪心算法,通过动态调整权重来确保:
权重大的服务器被选中的概率更高
但不会连续多次选择同一服务器
长期来看,选择比例精确匹配权重比例
2.2 数学依据:公平序列生成算法 ??
严格的数学理论:
平滑权重轮询算法基于以下数学原理:
设服务器i的权重为w?,总权重为T = Σw?
算法保证:
每个周期(T次请求)内,服务器i被选中 exactly w? 次
服务器i的两次被选中之间的最大间隔不超过 ?T/w??
序列的平滑度最优:方差最小化
算法可以形式化为:
对于每个请求t:
更新:c?(t) = c?(t-1) + w? 对于所有i
选择:i* = argmax? c?(t)
调整:c?(t) = c?(t) - T
通俗解释:
这就像给每个服务器发一张"积分卡"。每次请求前,大家都获得与能力相符的积分,积分最高者获得处理机会,但需要扣除"入场费"(总权重)。这样既能保证能力强的服务器获得更多机会,又能避免它们垄断所有请求。
2.3 代码实现深度解析 ??
public Server getNextServer() {
Server targetServer = null;
int maxWeight = Integer.MIN_VALUE;
// 第一步:所有服务器增加权重,并找出最大值
for (Server server : servers) {
int newWeight = server.getCurrentWeight() + server.getWeight();
server.setCurrentWeight(newWeight);
if (newWeight > maxWeight) {
maxWeight = newWeight;
targetServer = server;
}
}
// 第二步:选中服务器减去总权重
if (targetServer != null) {
targetServer.setCurrentWeight(targetServer.getCurrentWeight() - totalWeight);
return targetServer;
}
return servers.get(0);
}
算法复杂度分析:
时间复杂度:O(n),需要遍历服务器列表两次(可优化为一次)
空间复杂度:O(n),需要为每个服务器存储额外状态
线程安全:需要额外同步机制(示例代码未显示)
2.4 执行过程详细图示 ??
同样配置:ServerA(5), ServerB(3), ServerC(2), 总权重=10
详细执行过程:
请求 增加后权重 选中服务器 调整后权重 分配序列
1 ?? A:0+5=5, ?? B:0+3=3, ?? C:0+2=2 ?? A(max=5) ?? A:5-10=-5, ?? B:3, ?? C:2 A
2 ?? A:-5+5=0, ?? B:3+3=6, ?? C:2+2=4 ?? B(max=6) ?? A:0, ?? B:6-10=-4, ?? C:4 B
3 ?? A:0+5=5, ?? B:-4+3=-1, ?? C:4+2=6 ?? C(max=6) ?? A:5, ?? B:-1, ?? C:6-10=-4 C
4 ?? A:5+5=10, ?? B:-1+3=2, ?? C:-4+2=-2 ?? A(max=10) ?? A:10-10=0, ?? B:2, ?? C:-2 A
5 ?? A:0+5=5, ?? B:2+3=5, ?? C:-2+2=0 ?? A或B(都5) ?? A:5-10=-5, ?? B:5, ?? C:0 A
6 ?? A:-5+5=0, ?? B:5+3=8, ?? C:0+2=2 ?? B(max=8) ?? A:0, ?? B:8-10=-2, ?? C:2 B
7 ?? A:0+5=5, ?? B:-2+3=1, ?? C:2+2=4 ?? A(max=5) ?? A:5-10=-5, ?? B:1, ?? C:4 A
8 ?? A:-5+5=0, ?? B:1+3=4, ?? C:4+2=6 ?? C(max=6) ?? A:0, ?? B:4, ?? C:6-10=-4 C
9 ?? A:0+5=5, ?? B:4+3=7, ?? C:-4+2=-2 ?? B(max=7) ?? A:5, ?? B:7-10=-3, ?? C:-2 B
10 ?? A:5+5=10, ?? B:-3+3=0, ?? C:-2+2=0 ?? A(max=10) ?? A:10-10=0, ?? B:0, ?? C:0 A
分配序列:A, B, C, A, A, B, A, C, B, A
平滑性分析:
ServerA被选中5次(50%),但没有连续超过2次
ServerB被选中3次(30%),分布均匀
ServerC被选中2次(20%),间隔合理
三、两种算法对比分析 ??
3.1 理论基础对比
方面 非平滑权重轮询 平滑权重轮询
数学基础 模运算和区间划分 动态规划和贪心算法
序列性质 确定性、周期性 确定性、准周期性
平滑度 低(可能连续选择) 高(分布均匀)
公平性 长期比例公平 长期比例公平+短期平滑
3.2 性能特征对比 ??
特性 非平滑权重轮询 平滑权重轮询
?? 分配策略 区间映射,简单直接 动态调整,智能平滑
? 时间复杂度 O(n) O(n)
?? 空间复杂度 O(1) O(n)
?? 线程安全 容易(原子计数器) 较复杂(需要同步状态)
?? 可扩展性 好 较好
3.3 适用场景分析 ??
非平滑权重轮询适用场景:
?? 服务器处理能力差异大,能承受突发负载
?? 请求间隔较大,不需要考虑瞬时负载均衡
?? 对实现简单性要求高的场景
?? 资源受限环境(内存占用少)
平滑权重轮询适用场景:
?? 需要均匀分配请求,避免服务器瞬时压力
?? 服务器处理能力相近,需要精细负载均衡
?? 对响应时间一致性要求高的场景
?? 长期运行的服务,需要稳定性能
更多推荐
所有评论(0)