SpringBoot整合Redis:面试必考题-缓存击穿--逻辑过期解决

🎉🎉欢迎光临,终于等到你啦🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟持续更新的专栏Redis实战与进阶

本专栏讲解Redis从原理到实践

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net


本期讲解Redis企业必考面试题  缓存击穿使用逻辑过期解决

首先要了解什么是缓存击穿可以看我这一篇:http://t.csdnimg.cn/jMAqw

那么我们复原一下业务场景

分析思路

  1. 确定数据的更新逻辑:首先,需要明确数据的更新逻辑。了解数据是如何被修改、更新或者删除的,以及这些操作是由哪些业务逻辑触发的。这可以包括数据库更新、后端服务的数据变更通知等。

  2. 监听数据的更新事件:在数据被修改、更新或者删除时,需要能够捕捉到这些事件。这可以通过数据库的触发器(Trigger)机制、消息队列、发布-订阅模式等方式来实现。目的是在数据更新时能够及时感知到。

  3. 更新缓存和设置逻辑过期时间:当接收到数据更新事件时,需要更新相应的缓存,并重新设置逻辑过期时间。这意味着需要将最新的数据加载到缓存中,并根据业务规则设置适当的过期时间。这可以通过缓存服务的API或者命令来完成。

  4. 缓存访问时的逻辑判断:在每次访问缓存之前,需要进行逻辑判断以确定数据是否过期。这可以基于缓存中存储的逻辑过期时间和当前时间进行比较。如果数据已经过期,需要重新加载最新数据到缓存中。

  5. 数据加载的并发控制:在数据过期时,可能会有多个线程同时检测到数据过期并尝试重新加载数据到缓存。为了避免并发查询对后端服务造成压力,可以使用互斥锁或其他并发控制机制,确保只有一个线程负责重新加载数据,其他线程从缓存中获取旧数据。

  6. 定期刷新数据:除了根据数据更新事件进行缓存更新外,还可以定期刷新数据来保持缓存的新鲜性。定期刷新可以通过设置一个时间间隔,在规定的时间间隔内重新加载数据到缓存中,避免数据长时间未更新而导致的过期数据。

代码实现

首先

我们先写一个RedisData的类专门封装到期日期

@Data
public class RedisData {private LocalDateTime expireTime;private Object data;
}

然后在ShopServiceImpl中写一个专门处理逻辑过期的方法saveShop2Redis

//数据预热
private void saveShop2Redis(long id,long expireSeconds){//1.查询店铺数据Shop shop = getById(id);//2.封装逻辑过期时间RedisData redisData = new RedisData();redisData.setData(shop);redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds));//3.写入RedisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+id,JSONUtil.toJsonStr(redisData));
}

然后再写一个专门处理逻辑过期的方法queryWithLogicalExpiration

//搭建一个线程池
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
//解决缓存穿透问题
public Shop queryWithLogicalExpiration(long id){String key = CACHE_SHOP_KEY + id;//1.先查询RedisString Jsonshop = stringRedisTemplate.opsForValue().get(key);//2.判断是否存在if (StrUtil.isBlank(Jsonshop)){//不存在 直接返回空return null;}//3.命中 先反序列化为对象RedisData redisData = JSONUtil.toBean(Jsonshop, RedisData.class);Shop shop = JSONUtil.toBean((JSONObject) redisData.getData(), Shop.class);//4.查询是否过期if (redisData.getExpireTime().isAfter(LocalDateTime.now())){//5.未过期 直接返回return shop;}//6.过期 重构缓存String lockKey = LOCK_SHOP_KEY + id;//6.1获得互斥锁// 6.2判断是否成功if(tryLock(lockKey)){//6.3成功 开启新线程 实现重构缓存executor.submit(() ->{//重建缓存try {//这里做的就是1.先查数据库2.然后写入Redis  //其实就是重构缓存this.saveShop2Redis(id,30L);} catch (Exception e) {throw new RuntimeException(e);}finally {//关锁unLock(lockKey);}});}//6.4失败 直接返回旧数据return shop;}

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

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

相关文章

如何解决Modbus转Profinet网关通信不稳定或数据丢失问题

接到现场反映,在配置Modbus转Profinet网关时,出现Modbus转Profinet网关(XD-MDPN100)通信不稳定或数据丢失的问题,就这个问题特做出答疑。 解决Modbus转Profinet网关(XD-MDPN100)通信不稳定或数据…

【Java.mysql】——数据删改(DU) 附加数据库约束

目录 🚩更新(Update) 🚩删除(Delete) 🚩数据库约束 🎈约束类型 ✅NULL约束 ✅NNIQUE 唯一约束 ✅DEFAULT:默认值约束 ✅PRIMARY KEY:主键约束 ✅FOREIGN KEY:外键…

python Flask扩展:如何查找高效开发的第三方模块(库/插件)

如何找到扩展以及使用扩展的文档 一、背景二、如何寻找框架的扩展?三、找到想要的扩展四、找到使用扩展的文档五、项目中实战扩展 一、背景 刚入门python的flask的框架,跟着文档学习了一些以后,想着其实在项目开发中,经常会用到发…

jenkins配置源码管理的git地址时,怎么使用不了 credential凭证信息

前提 Jenkins使用docker部署 问题 (在jenlins中设置凭证的方式)在Jenkins的任务重配置Git地址,并且设置了git凭证,但是验证不通过,报错; 无法连接仓库:Command "git ls-remote -h -- http://192.1XX.0.98:X02/…

设计模式之建造者模式精讲

也叫生成器模式。将一个复杂的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 在建造者模式中,有如下4个角色: 抽象建造者(Builder):用于规范产品的各个组成部分,并进行抽象&…

Redis安装详细教程

Redis安装详细教程 文章目录 Redis安装详细教程前言一、windows下安装Redis1、下载地址2、启动redis服务3、连接redis 二、Linux下安装Redis:直接安装1、下载并安装 三、Linux下安装Redis:Docker中安装 前言 一、windows下安装Redis 1、下载地址 官方下…

腾讯云4核8G服务器多少钱一年?谁知道?

2024年腾讯云4核8G服务器租用优惠价格:轻量应用服务器4核8G12M带宽646元15个月,CVM云服务器S5实例优惠价格1437.24元买一年送3个月,腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图: 腾讯云4核8G服务器优惠价格 轻…

《深入Linux内核架构》第3章 内存管理(4)

目录 3.4 初始化内存管理 3.4.1 建立数据结构 3.4.2 特定于体系架构的设置 内核在内存中的布局 初始化步骤 分页机制的初始化 3.4.3 启动期间的内存管理 数据结构 初始化 与内核的接口 停用bootmem分配器 释放初始化数据 3.4 初始化内存管理 包括: 显式…

IHO S-100系列产品标准

1 什么是S-100? S-100《通用海道测量数据模型》是国际海道测量组织(IHO)推出的新一代海上空间地理信息国际标准,旨在克服传统S-57数字海道测量数据传输标准的局限。这一标准不仅兼容了更为丰富的数据类型,如影像与栅格数据、时变数据等,还摒弃了固定的编码格式要求,采用…

2024/03/27(C++·day3)

一、思维导图 二、完成下面类 代码 #include <cstring> #include <iostream>using namespace std;class myString { private:char *str; // 记录C风格的字符串int size; // 记录字符串的实际长度public:// 无参构造函数myString() : size(10){str new char[si…

MySQL数据库高级语句

文章目录 MySQL高级语句older by 排序区间判断查询或与且&#xff08;or 与and&#xff09;嵌套查询&#xff08;多条件&#xff09;查询不重复记录distinctcount 计数限制结果条目limit别名as常用通配符嵌套查询&#xff08;子查询&#xff09;同表不同表嵌套查询还能用于删除…

家用洗地机哪个型号质量好,性价比高?全方位盘点与推荐!

洗地机一推一拉就能轻松把污渍清理干净&#xff0c;比用传统清理工具打扫卫生方便多了&#xff0c;更加省时省力&#xff0c;但是该说不说&#xff0c;洗地机这种东西买对了是提升幸福感&#xff0c;买错了那可是要多糟心有多糟心&#xff0c;所以在买之前一定要做好攻略。 洗…