Redis实现高效的负载均衡算法
1. Redis存储设计
我们需要在 Redis 中存储以下信息:
- 配置列表(
List<Config>):存储所有配置项。 - 总权重:存储所有配置的总权重。
- 当前轮询状态:存储当前的轮询状态(如当前随机值或索引)。
2. 实现加权轮询
以下是改进后的代码,使用 Redis 来存储和管理状态。
WeightedConfigSelector
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Random;@Service
public class WeightedConfigSelector {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate NebulaProperties nebulaProperties;private static final String CONFIG_LIST_KEY = "nebula:config_list";private static final String TOTAL_WEIGHT_KEY = "nebula:total_weight";/*** 初始化配置到 Redis 中*/public void initialize() {List<NebulaProperties.Config> configs = nebulaProperties.getConfig();// 将配置列表存储到 Redis 中 redisTemplate.delete(CONFIG_LIST_KEY); // 清空旧数据 configs.forEach(config -> redisTemplate.opsForList().rightPush(CONFIG_LIST_KEY, config));// 计算总权重并存储 int totalWeight = configs.stream().mapToInt(NebulaProperties.Config::getWeight).sum();redisTemplate.opsForValue().set(TOTAL_WEIGHT_KEY, totalWeight);}/*** 根据权重从 Redis 中选择配置*/public NebulaProperties.Config selectConfig() {if (Boolean.FALSE.equals(redisTemplate.hasKey(CONFIG_LIST_KEY))) {initialize();}// 获取总权重 Integer totalWeight = (Integer) redisTemplate.opsForValue().get(TOTAL_WEIGHT_KEY);if (totalWeight == null || totalWeight == 0) {throw new RuntimeException("Total weight is zero or not initialized.");}// 随机生成一个值 int rand = new Random().nextInt(totalWeight);// 遍历配置列表,根据权重选择配置 List<Object> configList = redisTemplate.opsForList().range(CONFIG_LIST_KEY, 0, -1);if (configList == null || configList.isEmpty()) {throw new RuntimeException("No configs available in Redis.");}for (Object obj : configList) {NebulaProperties.Config config = (NebulaProperties.Config) obj;rand -= config.getWeight();if (rand < 0) {return config;}}return null; // 不应该到达这里 }
}
3. 控制器使用示例
在控制器中调用 WeightedConfigSelector 的 selectConfig 方法来获取加权选择的配置。
ConfigController
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ConfigController {@Autowiredprivate WeightedConfigSelector weightedConfigSelector;@GetMapping("/getConfig")public NebulaProperties.Config getConfig() {return weightedConfigSelector.selectConfig();}
}
4. 注意事项
- 性能优化
- 如果配置列表较大,可以将配置列表缓存到本地内存中,并定期从 Redis 同步更新。
- 配置变更
- 如果配置发生变更(如新增或删除配置),需要重新调用
initialize方法将最新配置同步到 Redis。
- 如果配置发生变更(如新增或删除配置),需要重新调用
- 线程安全
- Redis 的操作是线程安全的,因此可以放心在多线程环境中使用。
5. 总结
通过将配置列表和状态存储在 Redis 中,我们实现了一个支持分布式系统的加权轮询算法。Redis 的高性能和分布式特性确保了多个实例之间的状态一致性,同时 Spring Data Redis 提供了便捷的操作接口,简化了开发流程。
相关文章:
Redis实现高效的负载均衡算法
1. Redis存储设计 我们需要在 Redis 中存储以下信息: 配置列表(List<Config>):存储所有配置项。总权重:存储所有配置的总权重。当前轮询状态:存储当前的轮询状态(如当前随机值或索引&am…...
虚拟文件系统 VFS
目录 虚拟文件系统 VFS 文件系统挂载过程 虚拟文件系统 VFS 统一标准的系统调用接口: VFS定义了一组标准的文件操作API,如open(), read(), write(), close()等,使得用户空间的应用程序无需关心底层文件系统的具体类型。 下层文件系统必须实现…...
基于Android的民宿租赁系统的设计与实现
博主介绍:java高级开发,从事互联网行业多年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…...
数据链路层-STP
生成树协议STP(Spanning Tree Protocol) 它的实现目标是:在包含有物理环路的网络中,构建出一个能够连通全网各节点的树型无环逻辑拓扑。 选举根交换机: 选举根端口: 选举指定端口: 端口名字&…...
OceanBase环境搭建与熟悉全攻略:开启分布式数据库探索之旅
《OceanBase环境搭建与熟悉全攻略:开启分布式数据库探索之旅》 在当今数字化浪潮汹涌澎湃的时代,数据量呈爆炸式增长,业务对数据库的性能、可靠性和扩展性提出了前所未有的要求。OceanBase作为一款极具创新性的分布式数据库,正逐…...
tensor core实现flash_attn_mma_share_kv源码分析
一 源码分析 1.1 函数入口 void flash_attn_mma_stages_split_q_shared_kv(torch::Tensor Q, torch::Tensor K, torch::Tensor V, torch::Tensor O, int stages) {CHECK_TORCH_TENSOR_DTYPE(Q, torch::kHalf) // Q [B,H,N,D]CHECK_TORCH_TENSOR_DTYPE(K, torch::kHalf) // K …...
【源码解析】Java NIO 包中的 MappedByteBuffer
文章目录 1. 前言2. MappedByteBuffer3. 例子4. 属性5. 构造器6. mappingOffset、mappingAddress、mappingLength7. isLoaded 判断内存是否还在内存中8. load 方法将 ByteBuffer 加载到 Page Cache 中9. force 刷盘 1. 前言 上一篇文章我们介绍了 HeapByteBuffer 的源码&#…...
【Docker系列】容器内目录显示异常的解决之道
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
echarts:dataZoom属性横向滚动条拖拽不生效
问: 拖拽的过程中,第一次向右拖拽正常,然后就报错: echarts报错: var pointerOption pointerShapeBuilder[axisPointerType](axis,pixeValue,otherExtent),(axis,pixeValue,otherExtent)下划线红色报错:…...
25/1/12 算法笔记 剖析Yolov8底层逻辑
YOLOv8 是一种基于深度学习的目标检测和图像分割模型,属于 YOLO(You Only Look Once)系列的最新版本。YOLO 系列模型以其高效的实时目标检测能力而闻名,YOLOv8 在此基础上进行了一些优化和改进。 Yolov8的主要特点: …...
Python双指针
双指针 双指针:在区间操作时,利用两个下标同时遍历,进行高效操作 双指针利用区间性质可以把 O ( n 2 ) O(n^2) O(n2) 时间降低到 O ( n ) O(n) O(n) 反向扫描 反向扫描: l e f t left left 起点,不断往右走&…...
1、docker概念和基本使用命令
docker概念 微服务:不再是以完整的物理机为基础的服务软件,而是借助于宿主机的性能。以小量的形式,单独部署的应用。 docker:是一个开源的应用容器引擎,基于go语言开发的,使用时apache2.0的协议。docker是…...
数据结构与算法之链表: LeetCode 92. 反转链表 II (Ts版)
反转链表 II https://leetcode.cn/problems/reverse-linked-list-ii/description/ 描述 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 示例 1 输入&…...
【PPTist】插入形状、插入图片、插入图表
一、插入形状 插入形状有两种情况,一种是插入固定的形状, 一种是插入自定义的形状。 插入固定的形状时,跟上一篇文章 绘制文本框 是一样一样的,都是调用的 mainStore.setCreatingElement() 方法,只不多传的类型不一…...
三台Centos7.9中Docker部署Redis集群
Docker部署Redis集群 1. 安装 Docker 和 Docker Compose安装 Docker:安装 Docker Compose: 2. 配置 Redis 容器和网络3. 启动 Redis 容器4. 设置 Redis 集群4.1 集群创建异常处理 5. 验证和测试总结 如果 CentOS 服务器上还没有安装 Docker 和 Docker Co…...
Entity 的材质(棋盘、条纹、网格)
Entity 的材质 普通物体的材质 import { nextTick, onMounted, ref } from vue import * as Cesium from cesium // console.log(Cesium, Cesium)const viewer ref<any>(null)onMounted(() > { ... })let material Cesium.Color.YELLOW.withAlpha(0.5)Cesium.Colo…...
MACPA:fMRI连接性分析的新工具
摘要 不同脑区的共同激活为它们之间的功能交互或连接提供了一个有价值的衡量指标。元分析连接模型(MACM)是一种经过充分验证的研究某一特定区域共激活模式的方法,该方法对基于任务的功能磁共振成像(task-fMRI)数据进行种子点(seed-based)元分析。虽然MACM是一种强大…...
JavaScript-一份你的前端入门说明书(计算机专业)
一.简介 1.起源 JavaScript 起源于 1995 年,当时它主要是为了满足网页交互的需求而被创建。它最初的设计目的是为了让网页开发者能够在网页中添加一些简单的交互效果和动态内容。在那个时期,网页大多是静态的,而 JavaScript 的出现为网页带来了新的活力。Netscape 公司的 B…...
STM32供电参考设计
STM32供电参考设计 在图中有VDD,VSS和VDDA,VSSA两种类型的供电引脚,其数据手册解释如下: 令我不解的是:VDDA和VSSA必须分别连接到VDD和VSS,这是什么意思?有大佬能够解答一下吗?…...
python+fpdf:创建pdf并实现表格数据写入
目录 创建pdf文件对象 新增页 添加自定义字体 设置字体 设置文字颜色和背景色 插入内容 换行 插入图片 保存pdf 完整代码 安装:pip install fpdf 创建pdf文件对象 from fpdf import FPDF, Alignpdf FPDF() # 创建pdf文件对象 获取边距 print(pdf.l_…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
