Redis框架(八):大众点评项目 逻辑过期时间处理缓存击穿

news2025/4/17 4:26:29

大众点评项目 逻辑过期时间处理缓存击穿

  • 需求:逻辑过期时间处理缓存击穿
  • 业务实现
  • 总结

SpringCloud章节复习已经过去,新的章节Redis开始了,这个章节中将会回顾Redis实战项目 大众点评
主要依照以下几个原则

  1. 基础+实战的Demo和Coding上传到我的代码仓库
  2. 在原有基础上加入一些设计模式,stream+lamdba等新的糖
  3. 通过DeBug调试,进入组件源码去分析底层运行的规则和设计模式

代码会同步在我的gitee中去,觉得不错的同学记得一键三连求关注,感谢:
Redis优化-链接: RedisThreeStrategiesProject

需求:逻辑过期时间处理缓存击穿

在这里插入图片描述

上一节已经讲了下互斥锁
互斥锁本身是ok的,但是将当前资源锁住,后面的用户 只能查询等待
有没有更好的解决方式那?
这里可以设计逻辑过期时间

我们定义一个逻辑过期时间

  1. 当用户A过来,发现过期,通过互斥锁去更新Redis
  2. 这个期间,其他用户过来,可以异步去获得旧数据,而不是一直等待
  3. 这里就需要我们手动设置一个过期时间,定义相应的RedisData类,封装过期时间信息

在这里插入图片描述

业务实现

在这里插入图片描述

  1. 更新RedisData,获取过期时间,这里的时间是手动设置的
@Data
public class RedisData {

    private LocalDateTime expireTime;
    private Object object;
}

  1. 去单元测试中测试,向Redis注入热点信息
    public void saveShop2Redis(Long id, Long expireSeconds){
        Shop shop = getById(id);

        RedisData data = new RedisData();

        data.setObject(shop);
        data.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds));

        stringRedisTemplate.opsForValue().set(RedisConstants.CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(data));

    }
@SpringBootTest
class HmDianPingApplicationTests {

    @Resource
    private ShopServiceImpl shopService;

    @Test
    void testSaveShop(){

        for (int i = 1; i < 15; i++) {
            Long value = Long.valueOf(i);
            shopService.saveShop2Redis(value, 10L);
        }

    }

}
  1. 业务逻辑代码,个人写的,没有使用异步,本质上还是互斥锁
    //逻辑过期  个人写  并不能实现异步 还是阻塞
    public Result queryById2(Long id) {

        String key = RedisConstants.CACHE_SHOP_KEY + id;
        String shopStr = stringRedisTemplate.opsForValue().get(key);
        if(StrUtil.isBlank(shopStr)){
            return Result.fail("NULL");
        }


        RedisData data = JSONUtil.toBean(shopStr, RedisData.class);
        Shop shop = JSONUtil.toBean((JSONObject) data.getObject(), Shop.class);


        if(data.getExpireTime().isAfter(LocalDateTime.now())){
            return Result.ok(shop);
        }


        //过期了,就通过独立线程 -> 互斥锁处理缓存击穿
        String lockKey = RedisConstants.LOCK_SHOP_KEY + id;
        try {
            if (!tryLock(lockKey)) {
                Thread.sleep(50);
                return queryById(id);
            }

            shop = getById(id);
            log.debug("lockKey: " + lockKey + " shopByDB " + shop);

            if (shop == null) {
                return Result.fail("店铺类型不存在!");
            }
            data.setExpireTime(LocalDateTime.now().plusSeconds(3600));
            stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(data),   RedisConstants.CACHE_NULL_TTL, TimeUnit.HOURS);


        } catch (InterruptedException e) {
            throw new RuntimeException(e);
            /*e.printStackTrace();*/
        }finally {
            //删除暂时的key, 释放互斥锁
            stringRedisTemplate.delete(lockKey);
        }
        return Result.ok(shop);
    }

  1. 业务逻辑,已经更新,线程池引入,异步处理
    private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);

    @Override //逻辑过期时间 通过线程池进行处理
    public Result queryById(Long id) {
        //这里就是所有的热点数据保存到了Redis,直接去拿,热点数据没有TTL,只有过期时间这一字段
        String key = RedisConstants.CACHE_SHOP_KEY + id;
        String shopStr = stringRedisTemplate.opsForValue().get(key);
        if(StrUtil.isBlank(shopStr)){
            return Result.fail("店铺资格过期");
        }

        RedisData data = JSONUtil.toBean(shopStr, RedisData.class);
        Shop shop = JSONUtil.toBean((JSONObject) data.getObject(), Shop.class);

        if(data.getExpireTime().isAfter(LocalDateTime.now())){
            return Result.ok(shop);
        }

        //过期了,就通过独立线程 -> 互斥锁处理缓存击穿
        String lockKey = RedisConstants.LOCK_SHOP_KEY + id;
        if (!tryLock(lockKey)) {
            log.debug("lockKey: " + lockKey + " shopByDB " + shop);
            CACHE_REBUILD_EXECUTOR.submit(()->{
                try {
                    this.saveShop2Redis(id, 10L);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                    /*e.printStackTrace();*/
                }finally {
                    //删除暂时的key, 释放互斥锁
                    stringRedisTemplate.delete(lockKey);
                }
            });
        }

        if(shop==null){
            return Result.fail("店铺不存在");
        }

        return Result.ok(shop);
    }

总结

在这里插入图片描述

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

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

相关文章

七分钟教会你如何编写一个合格的测试用例

目录 1、测试用例的基本要素 2、根据测试用例去测试带来的好处 3、测试用例的设计方法 3.1、等价类 3.2、边界值 3.3、错误猜测法 3.4、场景法 3.5、因果图法 3.6、正交排列 4、怎样判断一个测试用例是好的测试用例 1、测试用例的基本要素 测试用例是为了实施测试而向…

基于LEACH和HEED的WSN路由协议研究与改进(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Google谷歌浏览器Post请求预见strict-origin-when-cross-origin跨域问题的 解决办法

问题概述 关于这个问题&#xff0c;后端接口开发完成&#xff0c;前端功能界面和函数方法体编写完成后&#xff0c;博主在前后端联调的时候遇到的&#xff0c;接口是调用成功了&#xff0c;但是没有返回任何结果&#xff0c; 错误信息&#xff1a;“ Referrer Policy: strict-…

C++中二叉树的非递归遍历方法2-1

1 二叉树简介 树是一种数学上的抽象&#xff0c;在算法的设计与分析中起到一个中心作用。树是有n个节点的有限集合。二叉树是树的一种特殊形式&#xff0c;这种树的每个节点最多有2个子节点。 2 二叉树的遍历方法 二叉树的遍历分为前序遍历、中序遍历、后序遍历和层序遍历四…

【华为上机真题 2022】寻找身高相近的小朋友

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

力扣(LeetCode)147. 对链表进行插入排序(C++)

排序 ①遍历链表&#xff0c;当前遍历的结点记作 ppp 。 ②从前往后遍历链表&#xff0c;找到最后一个值小于 ppp 的结点 curcurcur 。 ③(关键操作) 插入&#xff0c;如图&#xff0c;将 ppp 插入 curcurcur 的后面。 p->next cur->next; cur->next p; p next;…

关于Mac启动人人开源前端项目遇到node-sass下载不了的问题!

今天在网上看到了一个前后端分离用户管理系统&#xff0c;于是心血来潮下载下来看一看&#xff0c;结果发现前端项目中用Mac开发的话坑比较多 1.关于node版本问题 node版本最好不要太高&#xff0c;我对于该项目使用的node版本是v10.16.3 node版本最好使用nvm来管理&#xff0c…

[附源码]Python计算机毕业设计Django的图书互换系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

java基于springboot的在线电影评论投票系统

项目介绍 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代…

可以提高开发效率的vscode插件

1&#xff0c;koroFileHeader 我们在新建一个文件后&#xff0c;常常需要在文件头部加入默认注释&#xff0c;vscode中提供了一个 的插件&#xff0c;可以帮助我们实现。 1.1&#xff0c;安装插件 在vscode extensions中搜索并按照koroFileHeader 插件 installl完成后&…

大数据-HDFS的Shell操作

一、了解HDFS常用Shell命令 1、三种Shell命令方式 命令适用场合hadoop fs适用于任何不同的文件系统&#xff0c;比如本地文件系统和HDFS文件系统hadoop dfs只能适用于HDFS文件系统hdfs dfshdfs dfs跟hadoop dfs的命令作用一样&#xff0c;也只能适用于HDFS文件系统 2、常用HD…

基于C+++Mysql实现(WinForm)图书管理系统【100010034】

图书管理系统 实验内容、步骤以及结果 做出数据流图和数据字典。 在数据流图和字典的基础上做出 E-R 图(概念结构设计)。 学生&#xff1a; 图书&#xff1a; 管理员&#xff1a; 汇总&#xff1a; 在 E-R 图基础上进行关系模式设计&#xff08;至少满足 3NF&#xff09;&am…

b站黑马的Vue快速入门案例代码——计数器

目录 目标效果&#xff1a; 重点原理&#xff1a; 1.创建Vue实例的时候&#xff1a; 2.v-on——为元素绑定事件 3.v-text——【解析文本用】设置标签的文本值 v-text【简写】为{{}} 实现步骤&#xff1a; 代码部分&#xff1a; 1.计数器模板.html(全是重点&#xf…

【Redis缓存】主从、哨兵、 Cluster集群一锅端,一文带你全了解

Redis主从Redis哨兵Redis Cluster集群公众号&#xff1a;捡田螺的小男孩 \1. Redis 主从 面试官经常会问到Redis的高可用。Redis高可用回答包括两个层面&#xff0c;一个就是数据不能丢失&#xff0c;或者说尽量减少丢失;另外一个就是保证Redis服务不中断。 对于尽量减少数据…

KKALRRQETVDAL,129198-88-5,钙调蛋白激酶底物

Autocamtide 2是钙/钙调蛋白依赖的蛋白激酶II (CaMKII)的高选择性肽底物。 它可以用于测定CaMKII的活力。Autocamtide 2 is a highly selective peptide substrate of calcium/calmodulin-dependent protein kinase II (CaMKII). It can be used in the CaMKII activity assay.…

被天空盒裁剪

一般来说天空盒都是在最后一层&#xff0c;最近发现一个天空盒裁剪的问题 距离放的太远了被裁剪了。 经研究发现是因为平时因为怕摄像机近截面裁剪到近距离的物品&#xff0c;习惯改成0.然后系统会自动改成0.01 只要改成大于0.01的值就可以了&#xff0c;比如默认的0.3.就会…

web网页设计期末课程大作业:旅游网页主题网站设计——中国风的温泉酒店预订网(13页)HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

中高频多因子库存储最佳实践

1. 概述 因子挖掘是量化交易的基础。随着量化交易竞争的加剧&#xff0c;量化投资团队需要处理大量因子。在许多情况下&#xff0c;因子数据量甚至会远远超过高频的行情数据量。以 5,000 只股票 10,000 个因子为例&#xff0c;一年的 10 分钟线数据量为 2.3TB&#xff0c;1分钟…

卡塔尔世界杯出现了半自动越位识别技术、Feelix Palm、动作轨迹捕捉等黑科技,一起来看看吧。

1.史上最快比赛用球 本届世界杯的官方比赛用球名为“旅程&#xff08;Al Rihla&#xff09;”&#xff0c;由于重量很轻&#xff0c;因此在空中的飞行速度比以往任何一届世界杯的比赛用球都快。 “旅程”的球体表面由20个名为SPEEDSHELL的纹理聚氨酯球面材料模块组成&#xf…

一文看懂卷积运算(convolution)与互相关运算(cross-correlation)的区别

目录 互相关运算定义 互相关运算图示 互相关运算完整计算示例 卷积数学定义 卷积运算图示 卷积与互相关运算区别 深度学习中的卷积为何能用互相关运算代替 互相关运算定义 在二维互相关运算中&#xff0c;卷积窗口从输入数组的最左上方开始&#xff0c;按从左往右、从上…