Redis-缓存击穿-逻辑过期

Redis-缓存击穿-逻辑过期实现

缓存击穿:也称热点key问题,大量访问一个key,而这个key恰巧到期了,导致大量的请求访问数据库。增大数据库的负担。为了解决这个问题可以采用互斥锁或逻辑过期的方式解决。本章采用逻辑过期的方式解决此问题。

流程图:

第一点需要进行缓存预热,把经常用的key预先缓存到redis中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    /** 缓存数据KEY */private final String CACHE_SHOP_KEY = "CACHE_SHOP_KEY:";/** 缓存互斥锁KEY */private final String CACHE_SHOP_LOCK_KEY = "CACHE_SHOP_LOCK_KEY:";@Autowiredprivate StringRedisTemplate stringRedisTemplate;private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);/*** redis缓存* 缓存击穿*/@Overridepublic BooksVo selectById(Long bookId) {// 缓存击穿-互斥锁// return tryCacheMutex(bookId);// 缓存击穿-逻辑过期时间return tryCacheMutex2(bookId);}/*** redis缓存* 缓存击穿-逻辑过期版本* @param bookId*/private BooksVo tryCacheMutex2(Long bookId) {// RedisKeyString cacheKey = CACHE_SHOP_KEY + bookId;// 1.从Redis查询商铺缓存// 获取缓存数据String contentBook = stringRedisTemplate.opsForValue().get(cacheKey);// 2.判断缓存是否命中if (StringUtils.isBlank(contentBook)){// 3.1缓存未命中 直接返回结果return null;}// 3.2缓存命中-获取数据RedisData redisData = JSONUtil.toBean(contentBook, RedisData.class);BooksVo booksVo = JSONUtil.toBean((JSONObject) redisData.getData(), BooksVo.class);LocalDateTime expireSecond = redisData.getExpireSecond();//  4.缓存未过期 直接返回数据if (expireSecond.isAfter(LocalDateTime.now())){return booksVo;}// 5.缓存过期-获取互斥锁if (tryLock(bookId)){// check doubleString s = stringRedisTemplate.opsForValue().get(cacheKey);RedisData redisData1 = JSONUtil.toBean(s, RedisData.class);if (BooleanUtil.isFalse(redisData1.getExpireSecond().isAfter(LocalDateTime.now()))){// 获取互斥锁成功,开启独立线程,缓存重建CACHE_REBUILD_EXECUTOR.submit(() -> {try {// 重建缓存saveCacheBook(bookId, 20L);} catch (Exception e) {throw new RuntimeException(e);} finally {// 释放互斥锁stringRedisTemplate.delete(CACHE_SHOP_LOCK_KEY + bookId);}});}}// 返回已过期的数据return booksVo;}/*** 保存缓存信息*/public void saveCacheBook(Long bookId, Long expireSeconds){// 1.查询数据库数据BooksVo booksVo = this.queryById(bookId);// 2.封装逻辑过期时间RedisData redisData = new RedisData();redisData.setData(booksVo);// 获取当前的时间 + 指定秒数redisData.setExpireSecond(LocalDateTime.now().plusSeconds(expireSeconds));// 3.写入redisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + bookId, JSONUtil.toJsonStr(redisData));}

redisData实体类

@Data
public class RedisData {/** 逻辑过期时间 */private LocalDateTime expireSecond;/** 拓展实体类 */private Object data;
}

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

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

相关文章

React 组件生命周期对比:Class vs. 函数式

在 React 中,Class 组件和函数式组件的生命周期存在一些差异。通过对 React 中 Class 组件和函数式组件的生命周期进行对比,详细探讨了它们在设计哲学、生命周期管理和开发技巧上的异同。全面了解 React 中两种组件类型的生命周期特点,以及如…

比肩世界一流的车企,长安汽车的这些做法也太超前了!

2023年12月,法大大发布了中国首部《汽车行业合同数智化白皮书》(点击阅读及下载:中国首部!《汽车行业合同数智化白皮书》重磅发布 | 附下载)。该白皮书基于法大大自身参与汽车行业合同数智化建设的实践和思考&#xff…

量子飞跃:从根本上改变复杂问题的解决方式

内容来源:量子前哨(ID:Qforepost) 编辑丨王珩 编译/排版丨沛贤 深度好文:1000字丨5分钟阅读 利用多功能量子比特的量子计算机已处于解决复杂优化问题的最前沿,例如旅行商问题,这是一个典型的…

常见程序故障排查及程序配置

文章目录 故障排查基础关机/重启/注销系统信息和性能查看磁盘和分区⽤户和⽤户组⽹络和进程管理常⻅系统服务命令⽂件和⽬录操作⽂件查看和处理打包和解压RPM包管理命令YUM包管理命令DPKG包管理命令APT软件⼯具 分析工具JDK自带分析工具jpsjstatjinfojmapjhatjstackjcmd GUI分析…

Linux用户及用户组管理命令

Linux操作系统是一种基于UNIX的多用户、多任务的操作系统。在Linux系统中,用户和用户组的管理是非常重要的,因为它关系到系统安全和多用户环境下的资源共享。本文将详细介绍Linux中用户和用户组管理的相关命令,帮助用户更好地理解和管理Linux…

.NET MVC API Swagger 自动生成API文档入坑

开发环境 Win10 VS2022 .NET8.0 1.从NuGet添加Swagger 在解决方案资源管理器中右键单击项目>管理 NuGet 包 将包源设置为“nuget.org” 确保启用“包括预发行”选项 在搜索框中输入“Swashbuckle.AspNetCore” 从“浏览”选项卡中选择最新的“Swashbuckle.AspNetCore”包&a…

springboot 发布webservice接口

1. pom 文件加包 <dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.2.4</version></dependency><dependency><groupId>org.apache.cxf</groupId>&…

NVM的安装与配置

目录 一、简介二、下载2.1、windows环境下载地址2.2、安装 三、配置3.1、查看可安装版本3.2、安装版本3.3、使用和切换版本3.4、模块配置 四、其他4.1、全局安装pnpm4.2、常用nvm命令 一、简介 NVM&#xff0c;全称为Node Version Manager&#xff0c;是一个流行的命令行工具&a…

OpenHarmony实战开发-在Native侧实现进度通知功能。

介绍 本示例通过模拟下载场景介绍如何将Native的进度信息实时同步到ArkTS侧。 效果图预览 使用说明 点击“Start Download“按钮后&#xff0c;Native侧启动子线程模拟下载任务Native侧启动子线程模拟下载&#xff0c;并通过Arkts的回调函数将进度信息实时传递到Arkts侧 实…

ubuntu 使用conda 创建虚拟环境总是报HTTP错误,转换多个镜像源之后仍报错

最近在使用Ubuntu conda创建虚拟环境时&#xff0c;总是报Http错误&#xff0c;如下图所示&#xff1a; 开始&#xff0c;我以为是conda 镜像源的问题&#xff0c;但是尝试了好几个镜像源都不行&#xff0c;还是报各种各样的HTTP错误。后来查阅很多&#xff0c;总算解决了。解…

spring高级篇(一)

1、ApplicationContext与BeanFactory BeanFactory是ApplicationContext的父级接口&#xff1a;&#xff08;citlaltu查看类关系图&#xff09; 在springboot的启动类中&#xff0c;我们通过SpringApplication.run方法拿到的是继承了ApplicationContext的ConfigurableApplicatio…

PHP直播电商平台APP开发应该具有的功能和搭建之前应该思考的过程?

直播电商平台是一个充满活力和潜力的领域&#xff0c;可以为用户提供全新的购物体验。以下是一些开发和搭建直播电商平台的想法&#xff1a; 功能丰富的直播模块&#xff1a; 实现主播与观众之间的实时互动&#xff0c;包括文字聊天、语音聊天、送礼物、打赏等功能。 商品展示…