Redis-07-常见Redis使用场景

文章目录

    • 01.缓存数据(Cache)
    • 02.布式锁(Distributed Lock)
    • 03.计数器(Counter)
    • 04.排行榜(Leaderboard)
    • 05.消息队列(Message Queue)
    • 06.限流(Rate Limiting)
    • 07.会话存储(Session Storage)
    • 08.地理位置(Geo)
    • 09. 发布订阅(Pub/Sub)

01.缓存数据(Cache)

将数据库查询结果缓存到Redis,减轻数据库压力

示例:在电商网站中,可以将热门商品的信息存储在Redis中,当用户访问这些商品时,首先从Redis中读取,如果Redis中没有,再从数据库中读取并更新到Redis中。

@Service
public class ProductService {@Autowiredprivate ProductRepository productRepository;@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final String PRODUCT_CACHE_PREFIX = "product:";public Product getProductById(Long id) {String cacheKey = PRODUCT_CACHE_PREFIX + id;// 1. 先查缓存Product product = (Product) redisTemplate.opsForValue().get(cacheKey);if (product != null) {return product;}// 2. 缓存没有则查数据库product = productRepository.findById(id).orElse(null);if (product != null) {// 3. 写入缓存,设置过期时间redisTemplate.opsForValue().set(cacheKey, product, 30, TimeUnit.MINUTES);}return product;}
}

02.布式锁(Distributed Lock)

在分布式系统中,Redis可以用于实现分布式锁,可以在分布式系统中协调多节点对共享资源的访问,确保操作的原子性。

示例:分布式系统中用户购买商品,同一时间只能一个用户创建订单。

@Service
public class OrderService {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String LOCK_PREFIX = "lock:";private static final long LOCK_EXPIRE = 30; // 30秒public boolean createOrder(Long productId, Long userId) {String lockKey = LOCK_PREFIX + "order_" + productId;String requestId = UUID.randomUUID().toString();try {// 尝试获取锁Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, LOCK_EXPIRE, TimeUnit.SECONDS);if (Boolean.TRUE.equals(locked)) {// 获取锁成功,执行业务逻辑return doCreateOrder(productId, userId);}return false;} finally {// 释放锁 - 使用Lua脚本保证原子性String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"   return redis.call('del', KEYS[1]) " +"else " +"   return 0 " +"end";redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),Collections.singletonList(lockKey),requestId);}}
}

03.计数器(Counter)

Redis的原子增减操作非常适合用于计数器和排行榜应用,如社交媒体的点赞数、阅读数、排名等。

示例:实现文章阅读量、商品点击量等统计

@Service
public class ArticleService {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String VIEW_COUNT_PREFIX = "article:view:";// 增加阅读量public void incrementViewCount(Long articleId) {String key = VIEW_COUNT_PREFIX + articleId;redisTemplate.opsForValue().increment(key);}// 获取阅读量public Long getViewCount(Long articleId) {String key = VIEW_COUNT_PREFIX + articleId;String count = redisTemplate.opsForValue().get(key);return count == null ? 0L : Long.parseLong(count);}// 批量获取阅读量public Map<Long, Long> getBatchViewCounts(List<Long> articleIds) {List<String> keys = articleIds.stream().map(id -> VIEW_COUNT_PREFIX + id).collect(Collectors.toList());List<String> counts = redisTemplate.opsForValue().multiGet(keys);Map<Long, Long> result = new HashMap<>();for (int i = 0; i < articleIds.size(); i++) {Long articleId = articleIds.get(i);String count = counts.get(i);result.put(articleId, count == null ? 0L : Long.parseLong(count));}return result;}
}

04.排行榜(Leaderboard)

Redis的原子增减操作非常适合用于计数器和排行榜应用,如社交媒体的点赞数、阅读数、排名等。

示例:实现商品销量排行、游戏积分排行等

@Service
public class RankingService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final String SALES_RANK_KEY = "product:sales:rank";// 更新商品销量public void updateProductSales(Long productId, int sales) {redisTemplate.opsForZSet().add(SALES_RANK_KEY, productId, sales);}// 获取销量前N的商品public List<Long> getTopSalesProducts(int topN) {Set<Object> productIds = redisTemplate.opsForZSet().reverseRange(SALES_RANK_KEY, 0, topN - 1);return productIds.stream().map(id -> Long.parseLong(id.toString())).collect(Collectors.toList());}// 获取商品排名public Long getProductRank(Long productId) {// ZREVRANK返回的是从0开始的排名Long rank = redisTemplate.opsForZSet().reverseRank(SALES_RANK_KEY, productId);return rank == null ? null : rank + 1; // 转换为1-based排名}// 获取商品销量public Double getProductSales(Long productId) {return redisTemplate.opsForZSet().score(SALES_RANK_KEY, productId);}
}

05.消息队列(Message Queue)

Redis支持发布/订阅模式,可以用作轻量级的消息队列系统,用于异步任务处理、事件处理等。

示例:实现简单的消息队列系统

@Service
public class MessageQueueService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final String QUEUE_KEY = "message:queue";// 发送消息public void sendMessage(String message) {redisTemplate.opsForList().rightPush(QUEUE_KEY, message);}// 接收消息 - 阻塞式public String receiveMessage() throws InterruptedException {return (String) redisTemplate.opsForList().leftPop(QUEUE_KEY, 30, TimeUnit.SECONDS);}// 批量发送消息public void batchSendMessages(List<String> messages) {redisTemplate.executePipelined((RedisCallback<Object>) connection -> {for (String message : messages) {connection.listCommands().rPush(QUEUE_KEY.getBytes(), message.getBytes());}return null;});}
}

06.限流(Rate Limiting)

Redis 适合用于限流(Rate Limiting)场景。限流的目的是控制某个操作在特定时间内的访问频率,比如 API 请求、短信发送、登录尝试等。Redis 的原子操作和高效性能使其成为实现限流的理想工具。

示例:实现API访问限流

@Service
public class RateLimitService {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String RATE_LIMIT_PREFIX = "rate_limit:";/*** 限流检查* @param key 限流key(如用户ID或IP)* @param limit 时间窗口内允许的最大请求数* @param windowInSeconds 时间窗口大小(秒)* @return true-允许访问 false-拒绝访问*/public boolean allowRequest(String key, int limit, int windowInSeconds) {String redisKey = RATE_LIMIT_PREFIX + key;// 使用Lua脚本保证原子性String script = "local current = redis.call('incr', KEYS[1])\n" +"if current == 1 then\n" +"    redis.call('expire', KEYS[1], ARGV[1])\n" +"end\n" +"return current <= tonumber(ARGV[2])";Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),Collections.singletonList(redisKey),String.valueOf(windowInSeconds),String.valueOf(limit));return result != null && result == 1;}
}

07.会话存储(Session Storage)

在Web应用中,Redis常用于存储用户会话信息,如登录状态、购物车内容等。由于其快速的读写速度,Redis非常适合这种需要频繁访问和更新的数据。

示例:分布式系统中的会话存储

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800) // 30分钟过期
public class RedisSessionConfig {// Spring Session会自动配置Redis连接
}// 使用示例
@RestController
public class UserController {@PostMapping("/login")public String login(@RequestParam String username, HttpSession session) {// 存储用户信息到sessionsession.setAttribute("username", username);return "登录成功";}@GetMapping("/userinfo")public String getUserInfo(HttpSession session) {// 从session获取用户信息String username = (String) session.getAttribute("username");return "当前用户: " + (username != null ? username : "未登录");}
}

08.地理位置(Geo)

Redis支持地理空间数据,可以用于构建地理位置应用,如附近的人、地点推荐等功能。

示例:实现附近的人、附近的商家等功能

@Service
public class LocationService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final String GEO_KEY = "shop:locations";// 添加商家位置public void addShopLocation(Long shopId, double lng, double lat) {redisTemplate.opsForGeo().add(GEO_KEY, new Point(lng, lat), shopId.toString());}// 获取附近商家public List<Long> getNearbyShops(double lng, double lat, double radius) {Circle within = new Circle(new Point(lng, lat),  new Distance(radius, Metrics.KILOMETERS));RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending().limit(10);GeoResults<RedisGeoCommands.GeoLocation<Object>> results = redisTemplate.opsForGeo().radius(GEO_KEY, within, args);return results.getContent().stream().map(geoResult -> Long.parseLong(geoResult.getContent().getName().toString())).collect(Collectors.toList());}// 计算两个商家距离public Distance calculateDistance(Long shopId1, Long shopId2) {List<String> ids = Arrays.asList(shopId1.toString(), shopId2.toString());return redisTemplate.opsForGeo().distance(GEO_KEY, ids.get(0), ids.get(1), Metrics.KILOMETERS);}
}

09. 发布订阅(Pub/Sub)

示例:实现实时消息通知、事件广播等

// 配置消息监听容器
@Configuration
public class RedisPubSubConfig {@Beanpublic RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory,MessageListenerAdapter orderEventListenerAdapter) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);container.addMessageListener(orderEventListenerAdapter, new ChannelTopic("order:events"));return container;}@Beanpublic MessageListenerAdapter orderEventListenerAdapter(OrderEventListener listener) {return new MessageListenerAdapter(listener, "handleMessage");}
}// 消息监听器
@Component
public class OrderEventListener {public void handleMessage(OrderEvent event) {switch (event.getType()) {case CREATED:handleOrderCreated(event);break;case PAID:handleOrderPaid(event);break;// 其他事件处理...}}private void handleOrderCreated(OrderEvent event) {// 处理订单创建事件}
}// 消息发布服务
@Service
public class OrderEventPublisher {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;public void publishOrderEvent(OrderEvent event) {redisTemplate.convertAndSend("order:events", event);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/76158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

长亭2月公开赛Web-ssrfme

环境部署 拉取环境报错&#xff1a; 可以尝试拉取一下ubuntu:16.04&#xff0c;看是否能拉取成功 将wersion&#xff1a;"3"删掉 我拉去成功之后&#xff0c;再去拉取环境&#xff0c;成功&#xff01; 访问环境 测试ssrf 源码 <?php highlight_file(__file__…

RK3506+net9+VS2022跨平台调试C#程序

下载GetVsDbg.sh &#xff0c;这脚本会下载一个压缩包&#xff0c;然后解压缩&#xff0c;设置x权限等等。但是目标板子连不上&#xff0c;就想办法获取到下载路径&#xff0c;修改这个脚本&#xff0c;显示这个下载链接后&#xff0c;复制一下&#xff0c;用电脑下下来 修改好…

MySQL GTID集合运算函数总结

MySQL GTID 有一些运算函数可以帮助我们在运维工作中提高运维效率。 1 GTID内置函数 MySQL 包含GTID_SUBSET、GTID_SUBTRACT、WAIT_FOR_EXECUTED_GTID_SET、WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS 4个内置函数&#xff0c;用于GTID集合的基本运算。 1.1 GTID_SUBSET(set1,set2) …

Java学习手册:Java内存模型

Java内存模型&#xff08;Java Memory Model&#xff0c;简称JMM&#xff09;是Java语言中用于定义线程之间如何共享和操作内存的规范。它描述了Java程序中变量的内存可见性行为&#xff0c;并定义了线程之间的通信规则。理解Java内存模型对于编写正确的并发程序至关重要。本文…

神经网络优化 - 高维变量的非凸优化

网络优化是指寻找一个神经网络模型来使得经验(或结构)风险最小化的过程&#xff0c;包括模型选择以及参数学习等。 关于经验风险最小化和结构风险最小化&#xff0c;请参考博文&#xff1a; 认识机器学习中的经验风险最小化准则_样本均值近似与经验风险最小化的关系-CSDN博客…

Python自学第2天:条件语句,循环语句

条件语句 1.条件判断 score 60 if score > 90:print("优秀") elif score > 60:print("及格") else:print("不及格") 注意&#xff1a; 1、每个条件后面要使用冒号 :&#xff0c;表示接下来是满足条件后要执行的语句块。2、使用缩进来划…

C# dll 打包进exe

Framework4.x推荐使用 Costura.Fody 1. 安装 NuGet 包 Install-Package Costura.Fody工程自动生成packages文件夹&#xff0c;300M左右。生成FodyWeavers.xml、FodyWeavers.xsd文件。 2. 自动嵌入 编译后&#xff0c;所有依赖的 DLL 会被自动嵌入到 EXE 中。 运行时自动解压…

Redis之缓存更新策略

缓存更新策略 文章目录 缓存更新策略一、策略对比二、常见的缓存更新策略三、如何选择策略四、实际应用示例五、使用 Cache-Aside TTL 的方式&#xff0c;实现缓存商铺信息详情1.引入StringRedisTemplate2.将查询商铺信息加入缓存3.更新商铺信息时移除缓存总结 六、注意事项 一…

【工具变量】各地级市人口集聚及多中心程度数据集(2000-2023年)

多中心程度描述的是一个城市或区域内多个功能性中心的存在和分布情况&#xff1b;人口集聚度是指一定区域内人口的集中程度&#xff0c;它反映了区域内人口分布的不均衡性&#xff0c;这两个概念相互关联&#xff0c;通过分析地级市的多中心程度及人口集聚度可以帮助研究者理解…

函数对象-C++

1.定义 2.特点 、 1.解释第一句 #include<stdio.h> using namespace std; #include<string> #include<map> #include <iostream> class print { public:void operator()(string s){cout << s << endl;} }; int main() {print print;pri…

Apifox下载安装与使用

一、Apifox下载 官网地址:Apifox 点击"免费下载",即可进行下载。 二、Apifox安装 双击安装文件即可安装。

Python与图像处理:从基础操作到智能应用的全面解析

目录 一、Python图像处理的三大核心优势 1.1 生态库矩阵支撑 1.2 开发效率革命 1.3 跨领域协同能力 二、六大核心处理技术详解 2.1 图像基础操作 2.2 图像增强技术 2.3 特征提取算法 2.4 目标检测技术 2.5 图像分割技术 2.6 图像生成技术 三、实战案例&#xff1a;智…

双 Token 与 单 Token 优缺点

双Token与单Token认证机制对比 在Web应用开发中&#xff0c;身份认证和授权是保障系统安全的核心环节。随着技术演进&#xff0c;基于Token的认证机制逐渐取代传统Session方案&#xff0c;而双Token与单Token架构的选型争议也日益成为开发者关注的焦点。本文将从技术原理、优缺…

Spring Boot管理Spring MVC

Spring Boot真正的核心功能是自动配置和快速整合&#xff0c;通常Spring Boot应用的前端MVC框架依然使用Spring MVC。Spring Boot提供的spring-boot-starter-web启动器嵌入了Spring MVC的依赖&#xff0c;并为Spring MVC提供了大量自动配置&#xff0c;可以适用于大多数Web开发…

1.凸包、极点、极边基础概念

目录 1.凸包 2.调色问题 3.极性(Extrem) 4.凸组合(Convex Combination) 5.问题转化(Strategy)​编辑 6.In-Triangle test 7.To-Left-test 8.极边&#xff08;Extream Edges&#xff09; 1.凸包 凸包就是上面蓝色皮筋围出来的范围 这些钉子可以转换到坐标轴中&#xff0…

《如何用 Function 实现动态配置驱动的处理器注册机制?》

大家好呀&#xff01;&#x1f44b; 今天我们来聊聊一个超实用的技术话题 - 如何用Java的Function接口实现动态配置驱动的处理器注册机制。听起来很高大上&#xff1f;别担心&#xff0c;我会用最简单的方式讲清楚&#xff01;&#x1f60a; 一、为什么要用Function实现处理器…

【最新版】芸众商城独立版源码 425+插件 全新后台框架

一.系统介绍 芸众商城系统最新版 已经更新425全插件版&#xff0c;一套系统支持各种新零售、商城、模式&#xff0c;天天美丽链动商城。不要相信那些外面的旧版本。旧版本等于是废品&#xff0c;无法小程序运营的&#xff0c;框架还是旧的&#xff01; 芸众系统最新版 服务器可…

java 设计模式之单例模式

简介 单例模式&#xff1a;一个类有且仅有一个实例&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有一个对象被创建。 特点&#xff1a;类构造器私有、持有自己实例、对外提供获取实例的静态方法。 单例模式的实现方式 饿汉式 类被加载时&#xff0c;就会实例…

Milvus 索引如何选择

以下是几种索引类型的特点及适用场景&#xff0c;可据此选择&#xff1a; AUTOINDEX 特点&#xff1a;数据库自动选择合适索引类型&#xff0c;无需深入了解索引细节。适用场景&#xff1a;对索引知识了解有限&#xff0c;或不确定哪种索引适合当前数据和查询需求&#xff0c…

CentOS 7 安装教程

准备&#xff1a; 软件&#xff1a;VMware Workstation 镜像文件&#xff1a;CentOS-7-x86_64-bin-DVD1.iso &#xff08;附&#xff1a;教程较为详细&#xff0c;注释较多&#xff0c;故将操作的选项进行了加粗字体显示。&#xff09; 1、文件–新建虚拟机–自定义 2、硬盘…