负载均衡算法--加权随机法(Weight Random)

加权随机算法解析
本文深入探讨了加权随机算法在负载均衡中的应用,详细解释了如何根据服务器配置和负载分配权重,通过随机方式选择后端服务器,确保了高并发场景下的服务稳定性和效率。

接上一篇博文:负载均衡算法–随机法(Random),本文讲解加权随机算法。

与加权轮询法一样,加权随机法也根据服务器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。

算法描述

假设有 N 台服务器 S = {S0, S1, S2, …, Sn},默认权重为 W = {W0, W1, W2, …, Wn},权重之和为 weightSum, 服务器列表为 serverList,算法可以描述为:
1、初始化 serverList,将 W0 个 S0 加入至serverList,将 W1 个 S1 加入至serverList,依据此规则将所有的服务器加入至 serverList 中;
2、通过随机函数生成 0 到 weightSum 之间的任意整理,将该数字作为索引,从 serverList 中获取对应的服务器;

假定我们现在有如下四台服务器:

服务器地址权重
192.168.1.11
192.168.1.22
192.168.1.33
192.168.1.44

初始化服务列表后, serverList 如下:

服务器地址序号
192.168.1.11
192.168.1.22
192.168.1.23
192.168.1.34
192.168.1.35
192.168.1.36
192.168.1.47
192.168.1.48
192.168.1.49
192.168.1.410

与加权轮询算法类似,根据权重的不同向 serverList 添加相应的服务器,只不过服务器是通过随机算法获取的。

代码实现

1、服务器管理类

package org.learn.loadbalance;

import java.util.Map;
import java.util.TreeMap;

/**
 * @author zhibo
 * @date 2019/5/16 16:25
 */
public class ServerManager {
    public volatile static Map<String, Integer> serverMap = new TreeMap<>();

    static {
        serverMap.put("192.168.1.1", 1);
        serverMap.put("192.168.1.2", 2);
        serverMap.put("192.168.1.3", 3);
        serverMap.put("192.168.1.4", 4);
    }
}

2、加权随机类

package org.learn.loadbalance;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zhibo
 * @date 2019/5/16 16:28
 */
public class WeightRandom {

    public static String getServer() {
        ArrayList<String> serverList = new ArrayList<>();
        Set<String> serverSet = ServerManager.serverMap.keySet();
        Iterator<String> iterator = serverSet.iterator();

        Integer weightSum = 0;
        while(iterator.hasNext()){
            String server = iterator.next();
            Integer weight = ServerManager.serverMap.get(server);
            weightSum += weight;
            for (int i = 0; i < weight; i++) {
                serverList.add(server);
            }
        }

        Random random = new Random();
        String server = serverList.get(random.nextInt(weightSum));
        return server;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            String server = getServer();
            System.out.println(server);
        }
    }
}

1、使用 Random 对象随机生成 [0, serverList.size()) 的整数,然后通过索引获取到服务器。
2、在多线程的情况下, 线程A修改 ServerManager.serverMap 的值,线程B无法即时拿到线程A修改后的值,因此可能会产生请求错误,需要调用端进行容错处理。
3、从宏观的角度讲,访问量越大负载越均衡;微观的角度讲,看起来没有那么均衡。

执行 main 方法输出结果如下:
在这里插入图片描述
文章内容仅代表个人观点,如有不正之处,欢迎批评指正,谢谢大家。

### 随机算法负载均衡中的实现与原理 #### 1. **随机算法的定义与基本原理** 随机算法是一种简单的负载均衡策略,其核心思想是从可用的服务列表中随机选择一个服务实例来处理请求。这种方不依赖于任何历史状态或权重信息,完全基于概率分布进行决策[^5]。 随机算法的主要优势在于其实现简单、开销低,并且能够在一定程度上均匀分配流量到各个后端节点。然而,由于缺乏对当前系统负载状况的认知,可能导致某些情况下个别服务器承受过高的压力[^3]。 --- #### 2. **随机算法的具体实现** 以下是使用 Java 编写的随机算法的一个示例代码片段: ```java import java.util.List; import java.util.Random; public class RandomLoadBalancer { private final List<String> serverList; // 后端服务器地址集合 private final Random random = new Random(); public RandomLoadBalancer(List<String> serverList) { this.serverList = serverList; } /** * 随机选择一个服务器 */ public String selectServer() { int index = random.nextInt(serverList.size()); return serverList.get(index); } } ``` 在这个例子中,`serverList` 存储了所有可选的后端服务器地址。每当有新的请求到达时,`selectServer()` 方会生成一个介于 `[0, serverList.size()-1]` 的随机数作为索引值,进而返回对应的服务器地址[^5]。 对于更高级的应用场景,比如 Spring Cloud Load Balancer 中实现了类似的逻辑,默认提供了 `RandomLoadBalancer` 类型的支持[^5]。 --- #### 3. **随机算法的优点与局限性** ##### (1)优点 - **实现简单**:无需维护复杂的状态信息或者计算过程即可完成任务。 - **性能高效**:因为只需要执行少量算术运算就能得出结果,所以运行速度非常快。 - **适用范围广**:适用于大多数中小型规模部署环境下的基础负载分担需求[^4]。 ##### (2)局限性 - **无感知实时负载**:即使某台机器已经接近满负荷运转,仍然有可能被继续分配更多请求。 - **可能出现不均现象**:理论上虽然平均下来每台设备获得的机会相等,但由于统计波动的存在,在短时间内仍存在显著偏差的可能性。 --- #### 4. **随机算法的最佳实践与优化建议** 为了克服传统纯随机选取带来的潜在问题,可以通过引入加权因子等方式改进标准版本的随机算法。例如,“加权随机”就是在原有基础上增加了一个权重参数的概念,让那些拥有更高优先级/容量更大的主机更容易被挑中[^3]。 下面是一个带权重支持的 Python 实现案例: ```python import random def weighted_random_select(servers_with_weights): total_weight = sum(weight for _, weight in servers_with_weights) rand_num = random.uniform(0, total_weight) cumulative_sum = 0 for server, weight in servers_with_weights: cumulative_sum += weight if rand_num <= cumulative_sum: return server # 示例输入 [(ip_address, weight)] servers = [("192.168.1.1", 3), ("192.168.1.2", 1)] print(weighted_random_select(servers)) ``` 在此程序里,我们先累加全部权重得到总量;接着利用随机函数产生一个小于等于该总数的新数值;最后遍历一遍数组直至累积和超过刚才产生的那个随机量即停止并输出相应位置上的元素名作为最终选定对象。 --- #### 5. **随机算法的典型使用场景** - **小型集群环境**:当后台仅有少数几台物理机组成的小型群集时,采用随机算法足以满足日常运营所需[^4]。 - **高并发读取操作为主的服务架构下**:如果整个业务流程以内存缓存查询为代表的话,则完全可以忽略掉短时间内的轻微失衡情况[^2]。 - **无状态服务模型**:特别是像 CDN 这样的全球分布式网络边缘节点之间互相独立运作的情形之下更是如此。 --- ### 总结 综上所述,随机算法因其简洁明了的设计思路以及较低的技术门槛成为众多开发者入门学习阶段接触的第一种经典负载均衡方案之一。不过随着项目复杂度提升和技术栈扩展深入发展之后,往往还需要结合实际情况综合考量选用更适合当下条件限制的各种新型智能化调度手段才行。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值