Redis缓存穿透 缓存击穿 解析

先解析一下Redis中什么叫做 缓存穿透 和 缓存击穿

缓存穿透:首先我们要明确概念,缓存穿透是 在查询数据时 查询的数据在 redis 和 DB中都没有的 叫做缓穿透,解决方案,如果有这样的情况下 可以在第一次从DB中查询 判断结果是否为空 若为空 则直接 在redis中对应key的value存一个null 并且设置很短的过期时间

缓存击穿:Redis中没有 但DB中有;正常情况下我们查询同一条数据会先到Redis缓存中查取,如果没有再到数据库中查询,如果同一时间几千个用户查询同一条数据,在第一个线程到数据库中查询到了还未来得及更新到Redis里时剩下的线程也同时到数据库中查询,就无法体现Redis缓存的目的,这样被称为 Redis 缓存击穿,大批量请求直接到数据库中查询,很容易导致数据库直接奔溃。

我们看一下会导致 缓存击穿的代码:

redisConfig是我封装的一个类

请求到了这个service 先去的redis查询,查询不到才会去数据库查询,但是没有添加锁 故导致了 缓存击穿

@Overridepublic Student findStudent(String key) {    long l1 = System.currentTimeMillis();    log.info("先去redis里面去取...");    Student student = (Student) redisConfig.get("student-"+key);    if (null == student){        log.info("redis中没有查到,到数据库中去取...");        student = studentDao.getStudent(Integer.valueOf(key));        redisConfig.set("student-"+student.getId(),student);        long l2 = System.currentTimeMillis();        log.info("l2-l1:{}",l2-l1);    }    long l3 = System.currentTimeMillis();    log.info("l3-l1:{}",l3-l1);    return student;}# 我用Jmeter测试了一个高并发场景 从截图中可以看到 多个线程 多次到数据库中查询了

Redis缓存穿透 缓存击穿 解析

我们再看一下加了锁之后的代码:

也就再方法上加了一个 synchronized

@Overridepublic synchronized Student findStudent(String key) {    long l1 = System.currentTimeMillis();    log.info("先去redis里面去取...");    Student student = (Student) redisConfig.get("student-"+key);    if (null == student){        log.info("redis中没有查到,到数据库中去取...");        student = studentDao.getStudent(Integer.valueOf(key));        redisConfig.set("student-"+student.getId(),student);        long l2 = System.currentTimeMillis();        log.info("l2-l1:{}",l2-l1);    }    long l3 = System.currentTimeMillis();    log.info("l3-l1:{}",l3-l1);    return student;}

如截图所示 只有第一次去数据库中查询 剩下的线程都到Redis中查询 从实测的效果来看 缺点就是性能太差

Redis缓存穿透 缓存击穿 解析

我们再看一下双层检测锁的代码:

在方法内部加 synchronizedsynchronized内部再查一下redis

@Overridepublic Student findStudent(String key) {    long l1 = System.currentTimeMillis();    log.info("先去redis里面去取...");    Student student = redisConfig.get("student-"+key);    if (null == student){        //双层检测锁        synchronized (this){            student = redisConfig.get("student-" + key);            if (null == student){                log.info("redis中没有查到,到数据库中去取...");                student = studentDao.getStudent(Integer.valueOf(key));                redisConfig.set("student-"+student.getId(),student);                long l2 = System.currentTimeMillis();                log.info("l2-l1:{}",l2-l1);            }        }    }    long l3 = System.currentTimeMillis();    log.info("l3-l1:{}",l3-l1);    return student;}# 同样也解决了Redis 缓存击穿 的情况  性能会比在方法上添加 synchronized 好很多

Redis缓存穿透 缓存击穿 解析

总结:

从如上代码中可以看到 如果要解决Redis 缓存击穿的问题 在方法内添加 synchronized即可,建议使用双层检测锁 这样可以更大程度的保证性能;

Original: https://www.cnblogs.com/ganguixu/p/14901732.html
Author: 干桂旭
Title: Redis缓存穿透 缓存击穿 解析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/591892/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MYSQL–>视图

    视图就是一种 虚拟存在的表。因为视图的数据不在数据库中实际存在。 视图的行和列的数据都来自于 我们定义视图所使用的表 其中,定义视图所使用的表叫 基表 视图的行和列的数据是在使用视…

    数据库 2023年6月14日
    068
  • 打破千篇一律,DIY属于自己独一无二的商城

    随着线上购物成为了人们的主要消费之一,搭建商城系统也成为一大热门的发展方向,在现在的电商市场中,经营的主体规模非常庞大,各种各样的电商系统琳琅满目,但是只要仔细观察就会发现,有很大…

    数据库 2023年6月14日
    0107
  • linux常用命令(持续更新中…)

    查看所有开机启动服务:systemctl list-unit-files # 按Enter翻页 查看所有开机启动服务:systemctl list-unit-files | gre…

    数据库 2023年6月14日
    080
  • 当你想静下来的时候,你就可以静下来。

    当你想静下来的时候,你就可以静下来。1,2年前,我有时还在为当时选的专业恼悔,因为继续教育是同事推荐的,最后同事给我的消息是,他在疫情后去其他公司,做人工智能的公司,拿月薪20K,…

    数据库 2023年6月11日
    089
  • 【java框架】SpringBoot(11) — SpringBoot利用监听事件,实现异步操作

    请出主角:Spring当中的事件机制 没错,本节主要讲的是Spring中事件机制:ApplicationEventPublisher,实现监听ApplicationEvent,最后…

    数据库 2023年6月6日
    0138
  • JavaWeb核心篇(5)——Filter和Listener

    JavaWeb核心篇(5)——Filter和Listener JavaWeb具有三大组件:Servlet,Filter,Listener 在之前的文章中,我们已经学习了Servle…

    数据库 2023年6月14日
    099
  • 云数据库技术行业动态@2022-09-30

    重要更新 时序数据库厂商「格睿云Greptime」已于近期完成天使轮融资。据介绍,本轮融资金额在数百万美金级别,由耀途资本领投,九合创投跟投。Greptime成立于2022年4月,…

    数据库 2023年6月11日
    0108
  • 浅谈DDD中的聚合

    DDD分为战略部分跟战术部分,相信大家都认同DDD的核心在战略而非战术。而战略方面的核心我认为在业务建模,领域划分、统一语言等都在为业务建模服务。 为什么业务建模重要? 以前的开发…

    数据库 2023年6月14日
    081
  • window server2019+vmware16+Ubuntu20部署网站记录

    准备: 1:物理机一台,我的配置如下: 2:U盘10G以上一个,系统启动盘制作使用 3:Windows Server2019系统镜像 3-1:我下载的是server2019版本系统…

    数据库 2023年6月6日
    083
  • JUC学习笔记(五)

    创建线程的方法-一种是通过创建 Thread 类,另一种是通过使用 Runnable 创建线程。但是,Runnable 缺少的一项功能是,当线程终止时(即 run()完成时),我们…

    数据库 2023年6月6日
    0130
  • 14 在 Java 中,如何跳出当前的多重嵌套循环

    在最外层添加一个标记如A,然后用breakA,即可跳出多重循环 关键字break 使用范围:switch-case,循环结构中 break在循环结构中的作用:结束 当前循环 bre…

    数据库 2023年6月6日
    090
  • Linux–>磁盘分区,挂载

    对于IDE硬盘,驱动器标识符为 “hdx~”,其中”hd”表明分区所在设备类型,这里是指IDE硬盘 “x”为…

    数据库 2023年6月14日
    099
  • 回溯问题学习总结

    回溯问题 三种情况 每种情况都有子集,组合,排列三种题型 无重复元素不可复选 //子集问题 …

    数据库 2023年6月16日
    085
  • datatable 转化成xml以及json

    datatable dt=xxx获取 赋值给应用的字段 var pp=dt.row[0][“datatable里面的字段”].tostring() var …

    数据库 2023年6月9日
    084
  • 数据结构与算法-农夫过河问题

    农夫过河问题——最短路径算法 问题描述:农夫用小木筏将狼、羊、菜从起始岸运到目标岸,小木筏每次只能带一种物品,也可以什么都不带,因为食物链的关系,人不在的时候,狼会吃羊,羊会吃菜,…

    数据库 2023年6月14日
    0109
  • 从 KeyStore 中获取 PublicKey 和 PrivateKey

    KeyStore(译:密钥存储库) 代表用于加密密钥和证书的存储设施。 KeyStore 管理不同类型的 entry(译:条目)。每种类型的 entry 都实现了 KeyStore…

    数据库 2023年6月14日
    0104
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球