关于Redis的缓存穿透问题

 更新时间:2023年08月16日 08:30:08   作者:程序员阿红  
这篇文章主要介绍了关于Redis的缓存穿透问题,缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,需要的朋友可以参考下

1. 缓存穿透的理解

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。

2. 常见的解决方案有两种:

  • 1.缓存空对象
    • 优点:实现简单,维护方便
    • 缺点:
      • 额外的内存消耗
      • 可能造成短期的不一致
  • 2.布隆过滤
    • 优点:内存占用较少,没有多余key
    • 缺点:
      • 实现复杂
      • 存在误判可能

**缓存空对象思路分析:**当我们客户端访问不存在的数据时,先请求redis,但是此时redis中没有数据,此时会访问到数据库,但是数据库中也没有数据,这个数据穿透了缓存,直击数据库,我们都知道数据库能够承载的并发不如redis这么高,如果大量的请求同时过来访问这种不存在的数据,这些请求就都会访问到数据库,简单的解决方案就是哪怕这个数据在数据库中也不存在,我们也把这个数据存入到redis中去,这样,下次用户过来访问这个不存在的数据,那么在redis中也能找到这个数据就不会进入到缓存了

3. 布隆过滤:

布隆过滤器其实采用的是哈希思想来解决这个问题,通过一个庞大的二进制数组,走哈希思想去判断当前这个要查询的这个数据是否存在,如果布隆过滤器判断存在,则放行,这个请求会去访问redis,哪怕此时redis中的数据过期了,但是数据库中一定存在这个数据,在数据库中查询出来这个数据后,再将其放入到redis中,

假设布隆过滤器判断这个数据不存在,则直接返回

这种方式优点在于节约内存空间,存在误判,误判原因在于:布隆过滤器走的是哈希思想,只要哈希思想,就可能存在哈希冲突

image-20221209213419848

4. 编码解决查询的缓存穿透问题:

核心思路如下:

在原来的逻辑中,我们如果发现这个数据在mysql中不存在,直接就返回404了,这样是会存在缓存穿透问题的

现在的逻辑中:如果这个数据不存在,我们不会返回404 ,还是会把这个数据写入到Redis中,并且将value设置为空,当再次发起查询时,我们如果发现命中之后,判断这个value是否是null,如果是null,则是之前写入的数据,证明是缓存穿透数据,如果不是,则直接返回数据。

1653327124561

小总结:

缓存穿透产生的原因是什么?

  • 用户请求的数据在缓存中和数据库中都不存在,不断发起这样的请求,给数据库带来巨大压力

缓存穿透的解决方案有哪些?

  • 缓存null值
  • 布隆过滤
  • 增强id的复杂度,避免被猜测id规律
  • 做好数据的基础格式校验
  • 加强用户权限校验
  • 做好热点参数的限流

相关文章

  • Java 类在 Tomcat 中是如何加载的(过程分析)

    Java 类在 Tomcat 中是如何加载的(过程分析)

    这篇文章主要介绍了Java 类在 Tomcat 中是如何加载的过程分析,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • 一起学JAVA基础之运算符

    一起学JAVA基础之运算符

    计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量,下面这篇文章主要给大家介绍了关于JAVA基础之运算符的相关资料,需要的朋友可以参考下
    2022-01-01
  • IDEA创建的maven项目中pom.xml增加新依赖无效问题及解决

    IDEA创建的maven项目中pom.xml增加新依赖无效问题及解决

    在IDEA中,解决maven项目pom.xml增加依赖但外部库未更新的问题,可以通过设置"构建脚本更改后同步项目"选项为"任何更改",然后刷新Maven项目来解决
    2025-01-01
  • SpringBoot创建RSocket服务器的全过程记录

    SpringBoot创建RSocket服务器的全过程记录

    RSocket应用层协议支持 Reactive Streams语义, 例如:用RSocket作为HTTP的一种替代方案。这篇文章主要给大家介绍了关于SpringBoot创建RSocket服务器的相关资料,需要的朋友可以参考下
    2021-05-05
  • java实现Flappy Bird游戏源代码

    java实现Flappy Bird游戏源代码

    这篇文章主要为大家详细介绍了java实现Flappy Bird游戏源代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Java类加载器之ContextClassLoader详解

    Java类加载器之ContextClassLoader详解

    这篇文章主要介绍了Java类加载器之ContextClassLoader详解,ContextClassLoader是一种与线程相关的类加载器,类似ThreadLocal,每个线程对应一个上下文类加载器,需要的朋友可以参考下
    2023-10-10
  • SpringCloud断路器Hystrix原理及用法解析

    SpringCloud断路器Hystrix原理及用法解析

    这篇文章主要介绍了SpringCloud断路器Hystrix原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • springboot swagger 接口文档分组展示功能实现

    springboot swagger 接口文档分组展示功能实现

    这篇文章主要介绍了springboot swagger 接口文档分组展示功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • 使用Mybatis遇到的坑之Integer类型参数的解读

    使用Mybatis遇到的坑之Integer类型参数的解读

    这篇文章主要介绍了使用Mybatis遇到的坑之Integer类型参数的解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Maven清理java项目中未使用到 jar 依赖包的方法

    Maven清理java项目中未使用到 jar 依赖包的方法

    本文主要介绍了Maven清理java项目中未使用到 jar 依赖包的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02

最新评论