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_…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
