使用redis的5种常用场景
文章目录
- 1. 缓存热点数据
- 2. 分布式锁
- 3. 计数器和限流器
- 4. 消息队列
- 5. 会话管理
- 总结
在日常开发工作中,Redis作为一款高性能的内存数据库,凭借其强大的功能特性和卓越的性能表现,已经成为了许多项目中不可或缺的组件。本文将详细介绍Redis在实际工作中最常见的5种应用场景,并附上具体的代码实现。
1. 缓存热点数据
在高并发系统中,大量的数据库查询会对系统性能造成严重影响。通过Redis缓存热点数据,可以显著减少数据库的访问压力,提升系统响应速度。
实现示例:
public class ProductService {@Autowiredprivate RedisTemplate<String, Product> redisTemplate;@Autowiredprivate ProductMapper productMapper;private static final String PRODUCT_KEY_PREFIX = "product:";private static final long CACHE_TIMEOUT = 3600; // 缓存过期时间:1小时public Product getProduct(Long productId) {// 构建Redis键String redisKey = PRODUCT_KEY_PREFIX + productId;// 首先从Redis中查询Product product = redisTemplate.opsForValue().get(redisKey);if (product != null) {// 缓存命中,直接返回return product;}// 缓存未命中,查询数据库product = productMapper.selectById(productId);if (product != null) {// 将查询结果存入RedisredisTemplate.opsForValue().set(redisKey, product, CACHE_TIMEOUT, TimeUnit.SECONDS);}return product;}
}
2. 分布式锁
在分布式系统中,常常需要控制对共享资源的访问。Redis的SETNX命令提供了一种实现分布式锁的简单方法。
实现示例:
public class RedisLock {@Autowiredprivate StringRedisTemplate redisTemplate;private static final long LOCK_TIMEOUT = 10000; // 锁超时时间:10秒public boolean acquireLock(String lockKey, String requestId) {// 使用SETNX命令尝试获取锁Boolean isLocked = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId,LOCK_TIMEOUT,TimeUnit.MILLISECONDS);return Boolean.TRUE.equals(isLocked);}public boolean releaseLock(String lockKey, String requestId) {// 使用Lua脚本确保原子性操作String script = "if redis.call('get', KEYS[1]) == ARGV[1] then "+ "return redis.call('del', KEYS[1]) "+ "else "+ "return 0 "+ "end";Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),Collections.singletonList(lockKey),requestId);return Long.valueOf(1).equals(result);}
}
3. 计数器和限流器
Redis的INCR命令可以原子性地实现计数器功能,非常适合用于实现访问统计和接口限流。
实现示例:
public class RateLimiter {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String RATE_LIMIT_PREFIX = "rate:limit:";private static final int MAX_REQUESTS = 100; // 每分钟最大请求次数public boolean isAllowed(String userId) {String key = RATE_LIMIT_PREFIX + userId;// 获取当前时间的分钟数作为窗口long currentMinute = System.currentTimeMillis() / (60 * 1000);String windowKey = key + ":" + currentMinute;// 原子性增加计数Long count = redisTemplate.opsForValue().increment(windowKey);if (count == 1) {// 设置过期时间为1分钟redisTemplate.expire(windowKey, 60, TimeUnit.SECONDS);}// 判断是否超过限制return count <= MAX_REQUESTS;}
}
4. 消息队列
虽然Redis不是专门的消息队列系统,但它的List数据结构配合LPUSH和BRPOP命令可以实现简单的消息队列功能。
实现示例:
public class RedisMessageQueue {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String QUEUE_KEY = "message:queue";// 生产者public void sendMessage(String message) {redisTemplate.opsForList().leftPush(QUEUE_KEY, message);}// 消费者@Asyncpublic void consumeMessage() {while (true) {try {// 阻塞式获取消息List<String> message = redisTemplate.opsForList().rightPop(QUEUE_KEY,30,TimeUnit.SECONDS);if (message != null) {// 处理消息processMessage(message);}} catch (Exception e) {log.error("处理消息出错", e);}}}private void processMessage(List<String> message) {// 具体的消息处理逻辑}
}
5. 会话管理
Redis的Hash数据结构非常适合存储用户会话信息,支持部分字段的更新,且可以设置过期时间。
实现示例:
public class SessionManager {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String SESSION_KEY_PREFIX = "session:";private static final long SESSION_TIMEOUT = 1800; // 会话超时时间:30分钟public void saveSession(String sessionId, Map<String, String> sessionData) {String key = SESSION_KEY_PREFIX + sessionId;// 使用Hash结构存储会话数据redisTemplate.opsForHash().putAll(key, sessionData);// 设置过期时间redisTemplate.expire(key, SESSION_TIMEOUT, TimeUnit.SECONDS);}public void updateSessionField(String sessionId, String field, String value) {String key = SESSION_KEY_PREFIX + sessionId;// 更新单个字段redisTemplate.opsForHash().put(key, field, value);// 刷新过期时间redisTemplate.expire(key, SESSION_TIMEOUT, TimeUnit.SECONDS);}public Map<Object, Object> getSession(String sessionId) {String key = SESSION_KEY_PREFIX + sessionId;return redisTemplate.opsForHash().entries(key);}public void deleteSession(String sessionId) {String key = SESSION_KEY_PREFIX + sessionId;redisTemplate.delete(key);}
}
总结
Redis凭借其出色的性能和丰富的数据结构,在实际工作中可以解决很多具体问题。上述5种场景只是Redis应用的冰山一角,在实际开发中,我们还可以根据具体需求,结合Redis的特性来设计更多的解决方案。
在使用Redis时,需要注意以下几点:
- 合理设置过期时间,避免内存占用过大
- 注意缓存与数据库的一致性问题
- 在分布式环境下要考虑并发问题
- 根据实际需求选择合适的数据结构
- 定期监控Redis的内存使用情况和性能指标
相关文章:
使用redis的5种常用场景
文章目录 1. 缓存热点数据2. 分布式锁3. 计数器和限流器4. 消息队列5. 会话管理总结 在日常开发工作中,Redis作为一款高性能的内存数据库,凭借其强大的功能特性和卓越的性能表现,已经成为了许多项目中不可或缺的组件。本文将详细介绍Redis在实…...
微信小程序防止重复点击事件
直接写在app.wpy里面,全局可以调用 // 防止重复点击事件preventActive(fn) {const self this;if (this.globalData.PageActive) {this.globalData.PageActive false;if (fn) fn();setTimeout(() > {self.globalData.PageActive true;}, 3000); //设置该时间内…...
PySpark用sort-merge join解决数据倾斜的完整案例
假设有两个大表 table1 和 table2 ,并通过 sort-merge join 来解决可能的数据倾斜问题。 from pyspark.sql import SparkSession from pyspark.sql.functions import col# 初始化SparkSession spark SparkSession.builder.appName("SortMergeJoinExample&quo…...
sklearn-逻辑回归-制作评分卡
目录 数据集处理 分箱 分多少个箱子合适 分箱要达成什么样的效果 对一个特征进行分箱的步骤 分箱的实现 封装计算 WOE 值和 IV值函数 画IV曲线,判断最佳分箱数量 结论 pd.qcut 执行报错 功能函数封装 判断分箱个数 在银行借贷场景中,评分卡是…...
scrapy爬取图片
scrapy 爬取图片 环境准备 python3.10scrapy pillowpycharm 简要介绍scrapy Scrapy 是一个开源的 Python 爬虫框架,专为爬取网页数据和进行 Web 抓取而设计。它的主要特点包括: 高效的抓取性能:Scrapy 采用了异步机制,能够高效…...
在 Vue 项目中使用地区级联选
在 Vue 项目中使用地区级联选择的完整流程: 1.安装依赖包,这个包提供了中国省市区的完整数据。 npm install element-china-area-data --save 2.导入数据 import { regionData } from element-china-area-data 这个包提供了几种不同的数据格式&#…...
【简博士统计学习方法】第1章:1. 统计学习的定义与分类
自用笔记 1. 统计学习的定义与分类 1.1 统计学习的概念 统计学习(Statistical Machine Learning)是关于计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析的一门学科。 以计算机和网络为平台;以数据为研究对象;以…...
利用 Python 脚本批量创建空白 Markdown 笔记
文章目录 利用 Python 脚本批量创建空白 Markdown 笔记1 背景介绍2 需求描述3 明确思路4 具体实现4.1. 遍历 toc.md 文件,收集文件名和对应的文件内容4.2. 实现文件批量生成逻辑4.3. 补全缺失的工具函数4.4. 进一步补全工具函数中的工具函数 5 脚本运行6 注意事项 利…...
【Qt】C++11 Lambda表达式
1. 举例 connect(ui->pushButton, &QPushButton::clicked, [](bool checked){//具体代码qDebug() << "Hello" << checked;}); 2. 详情 //完整形式 [ capture ] ( params ) opt -> ret { body; }; capture 是捕获列表params 是参数表opt 是函数…...
怎样提高服务器中的数据传输速度?
服务器中的数据传输速度会影响着用户的体验感,当企业中的数据传输速度出现卡顿或者是过慢时,用户不能及时浏览到所需的内容,给用户造成不好的体验感,那么企业该怎样才能提高服务器中的数据传输速度呢? 服务器之间如何传…...
Vue 封装公告滚动
文章目录 需求分析1. 创建公告组件Notice.vue2. 注册全局组件3. 使用 需求 系统中需要有一个公告展示,且这个公告位于页面上方,每个页面都要看到 分析 1. 创建公告组件Notice.vue 第一种 在你的项目的合适组件目录下(比如components目录&a…...
JVM实战—12.OOM的定位和解决
大纲 1.如何对系统的OOM异常进行监控和报警 2.如何在JVM内存溢出时自动dump内存快照 3.Metaspace区域内存溢出时应如何解决(OutOfMemoryError: Metaspace) 4.JVM栈内存溢出时应如何解决(StackOverflowError) 5.JVM堆内存溢出时应该如何解决(OutOfMemoryError: Java heap s…...
【python翻译软件V1.0】
如果不想使用密钥的形式,且需要一个直接可用的中英文翻译功能,可以使用一些免费的公共 API,如 opencc 或其他无需密钥的库,或直接用 requests 获取翻译结果。 其中,我可以给你一个简单的代码示例,使用 tra…...
Spring Boot中的依赖注入是如何工作
Spring Boot 中的依赖注入(Dependency Injection,简称 DI)是通过 Spring 框架的核心机制——控制反转(Inversion of Control,IOC)容器来实现的。Spring Boot 基于 Spring Framework,在应用中自动…...
ubuntu22.04 编译安装libvirt 10.x
环境安装 sudo apt-get update -y sudo apt-get install qemu-system-x86 bridge-utils libyajl-dev -y sudo apt-get install build-essential autoconf automake libtool -y sudo apt-get install libxml2-dev libxslt1-dev libgnutls28-dev libpciaccess-dev libnl-3-de…...
[fastadmin] 第三十四篇 FastAdmin 商城模块标签使用详解
FastAdmin 商城模块标签使用详解 一、标签基本语法 1.1 基础语法格式 {shop:goodslist flag"参数值" id"变量名" row"数量"}<!-- 循环内容 --> {/shop:goodslist}1.2 常用参数说明 flag: 商品标记筛选id: 循环变量名row: 显示数量 1.…...
(2024,LLaVA-Bench (Wilder),LLaVA-NeXT,LLaMA3,Qwen-1.5,语言模型扩展)
LLaVA-NeXT: Stronger LLMs Supercharge Multimodal Capabilities in the Wild 目录 1. 简介 2. 探索大规模语言模型的能力极限 3. LLaVA-Bench (Wilder):日常生活视觉聊天基准 4. Benchmark 结果 1. 简介 我们通过引入近期更强大的开源大语言模型(…...
IPEX-LLM开发项目过程中的技术总结和心得
IPEX-LLM开发项目过程中的技术总结和心得 在人工智能快速发展的时代,高效地开发和部署大语言模型(LLM)已成为技术人员的必备技能。在我们的项目中,我们采用了 Intel Extension for PyTorch(简称 IPEX)和 L…...
HTTP/HTTPS ②-Cookie || Session || HTTP报头
这里是Themberfue 上篇文章介绍了HTTP报头的首行信息 本篇我们将更进一步讲解HTTP报头键值对的含义~~~ ❤️❤️❤️❤️ 报头Header ✨再上一篇的学习中,我们了解了HTTP的报头主要是通过键值对的结构存储和表达信息的;我们已经了解了首行的HTTP方法和UR…...
【软考】软件设计师
「学习路线」(推荐该顺序学习,按照先易后难排序) 1、上午题—计算机系统(5~6分)[1.8; ] 2、上午题—程序设计语言(固定6分)[1.9; ] 3、下午题—试题一(15分) 4、上午题—…...
2026年初中生赴新加坡留学,费用究竟几何?一文为你揭秘!
在教育全球化的今天,越来越多的家长将目光投向海外,新加坡凭借其优质的教育资源、安全的社会环境和多元的文化氛围,成为众多初中生留学的热门选择。那么,2026年初中生赴新加坡留学的费用到底是多少呢?本文将为你详细揭…...
告别预编译:手把手教你从源码编译Scrcpy的Android Server端(含Meson配置详解)
从零构建Scrcpy Android Server端:Meson与Gradle深度协作指南 在Android投屏工具Scrcpy的生态中,大多数用户都习惯于直接使用预编译的Server端APK。但当你需要修改投屏协议、优化视频编码参数或添加自定义功能时,从源码完整编译Server端就成为…...
避坑指南:在CentOS 7上部署泛微Ecology9 OA,我踩过的那些“内存不足”和“防火墙”的坑
CentOS 7部署泛微Ecology9 OA系统:从内存优化到防火墙配置的深度避坑指南 在Linux环境下部署企业级OA系统从来都不是一件简单的事情,尤其是像泛微Ecology9这样功能复杂的大型系统。表面上看,官方文档和网络上的教程似乎已经提供了完整的步骤&…...
TTK插件系统扩展指南:自定义Golden生成函数和输入数据生成函数的完整教程
TTK插件系统扩展指南:自定义Golden生成函数和输入数据生成函数的完整教程 【免费下载链接】ops-test-kit TTK(Ops Test Tool Kit)是CANN算子库提供的全链路、自动化、批量化算子测试框架,帮助开发者快速完成算子批量功能验证、性能…...
3步掌握TransNet V2:从零开始实现智能视频镜头检测
3步掌握TransNet V2:从零开始实现智能视频镜头检测 【免费下载链接】TransNetV2 TransNet V2: Shot Boundary Detection Neural Network 项目地址: https://gitcode.com/gh_mirrors/tr/TransNetV2 想要快速分析视频内容结构,自动识别镜头切换点吗…...
ToastFish:如何在Windows通知栏中偷偷背单词的终极指南
ToastFish:如何在Windows通知栏中偷偷背单词的终极指南 【免费下载链接】ToastFish 一个利用摸鱼时间背单词的软件。 项目地址: https://gitcode.com/GitHub_Trending/to/ToastFish 你是否曾经在忙碌的工作间隙想要学习英语,却又担心被同事或老板…...
告别Unity WebGL的模糊UI:用Vue3重构前端界面,手把手教你实现双向通信
Unity WebGL与Vue3的完美联姻:打造高清交互界面的实战指南 1. 为什么需要重构Unity WebGL的UI系统? 许多Unity开发者都曾经历过这样的困境:当我们将精心制作的3D项目发布为WebGL版本时,原生UGUI在浏览器中的表现往往不尽如人意。模…...
别再复制粘贴了!手把手教你用C语言实现MODBUS CRC-16校验(附5种算法对比)
MODBUS CRC-16校验算法实战指南:从原理到最优实现选择 在工业自动化领域,MODBUS协议因其简单可靠而广泛应用,而CRC-16校验则是保障数据完整性的关键环节。许多开发者习惯直接复制网络上的校验代码,却常常遇到内存溢出、性能瓶颈或…...
04. 骨架:后端分层架构与 TypeScript 类型系统实战
写在前面: 很多 GIS 开发者在写后端时,容易陷入“脚本思维”:一个文件几千行,数据库查询、业务逻辑、接口响应全混在一起。刚开始跑得快,但随着功能增加,代码会变成一团难以维护的“意大利面”。 在 light-mvt-server 中,我们坚持采用企业级的分层架构。今天,我们将深入…...
小红书无水印下载终极指南:如何用XHS-Downloader快速保存优质内容
小红书无水印下载终极指南:如何用XHS-Downloader快速保存优质内容 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用…...
