【Redis】缓存穿透问题及其解决方案

news2025/1/19 20:28:52

【Redis】缓存穿透问题及其解决方案

文章目录

  • 【Redis】缓存穿透问题及其解决方案
    • 1. 缓存穿透概念及原因
    • 2. 解决方案
      • 2.1 缓存空对象
        • 2.1.1 缓存空对象的优缺点
        • 2.1.2 改进代码
      • 2.2 布隆过滤
        • 2.2.1 布隆过滤的优缺点

1. 缓存穿透概念及原因

缓存穿透:客户端请求的数据在 缓存数据库 当中都不存在的情况,这样缓存就形同虚设,请求都会直接打到数据库。请求量过大时容易可能造成数据库的宕机。

缓存穿透通常都是人为恶意制造的,因为前端一般不会出现明显bug,但是后端因为对数据的校验不够仔细或者因为数据库本身设计的一些问题,很容易被别人通过测试工具直接请求接口并携带一些特别的参数,这样就会造成了缓存穿透。


2. 解决方案

缓存穿透的常见解决方案有两种:

  1. 缓存空对象
  2. 布隆过滤

我们先设定一个场景:假设这是一个电商平台,我们通过id去查询店铺信息。没处理缓存穿透问题的代码如下:

@Override
public Result queryById(Long id) {
    //1.从redis查询商铺缓存
    String key = CACHE_SHOP_KEY + id;
    String shopJson = stringRedisTemplate.opsForValue().get(key);
    //2.判断是否存在
    if (StrUtil.isNotBlank(shopJson)) {
        //3.存在,直接返回
        Shop shop = JSONUtil.toBean(shopJson, Shop.class);
        return Result.ok(shop);
    }
    //4.缓存数据不存在,根据id查询数据库
    Shop shop = getById(id);
    //5.不存在,返回错误
    if (shop == null) {
        return Result.fail("商铺不存在");
    }
    stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);
    return Result.ok(shop);
}

接下来解释两种解决方案及其改进代码。


2.1 缓存空对象

缓存空对象的实现流程如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9LL41aWf-1673424035601)(C:\Users\zhuhuanjie\AppData\Roaming\Typora\typora-user-images\image-20230111150639152.png)]

解释:当客户端发送请求到达redis时,发现redis中无数据,然后请求继续去查询数据库,发现数据库中也没有数据,那么为防止接下来有很多请求都来查询数据库,所以当数据库查询数据为空时,我们给redis中缓存一个空对象并设置一个过期时间TTL,那么接下来携带和第一次请求相同参数的请求就会直接在redis中获得空对象,然后直接命中返回。


2.1.1 缓存空对象的优缺点

优点:

  • 实现简单,维护方便

缺点:

  • 额外的内存消耗(可能会缓存很多的空对象)
  • 可能造成短期的不一致(缓存空对象的时候数据库没有对应数据,缓存之后数据库就有了对应数据,这样redis和数据库就不一致了,只能等待TTL到期再次查询才能保持一致)

2.1.2 改进代码

改进之后的流程图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ki9lKoV0-1673424035602)(C:\Users\zhuhuanjie\AppData\Roaming\Typora\typora-user-images\image-20230111155354058.png)]

具体代码如下:

@Override
public Result queryById(Long id) {
    //1.从redis查询商铺缓存
    String key = CACHE_SHOP_KEY + id;
    String shopJson = stringRedisTemplate.opsForValue().get(key);
    //2.判断是否存在
    if (StrUtil.isNotBlank(shopJson)) {
        //3.存在,直接返回
        Shop shop = JSONUtil.toBean(shopJson, Shop.class);
        return Result.ok(shop);
    }
    //此时 shopJson 不是为null就是为""
    if (shopJson != null) {
        //为""直接返回错误信息,为null查询数据库
        return Result.fail("商铺不存在");
    }
    //4.缓存数据不存在,根据id查询数据库
    Shop shop = getById(id);
    //5.不存在,返回错误
    if (shop == null) {
        //缓存空值
        stringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);
        return Result.fail("商铺不存在");
    }
    stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);
    return Result.ok(shop);
    }

仔细比对缓存空对象改进代码和原代码的区别。


2.2 布隆过滤

布隆过滤的实现流程如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yb1Nq28b-1673424035602)(C:\Users\zhuhuanjie\AppData\Roaming\Typora\typora-user-images\image-20230111151511053.png)]

解释:客户端的请求首先到达布隆过滤器,布隆过滤器存储的结果是数据库中数据hash之后得到的结果,如果布隆过滤器判断请求的数据不存在那么就一定不存在,如果判断存在那么也不一定真的存在(不同数据hash的结果可能相同)。假设判断数据不存在则直接拒绝请求;如果判断数据存在则放行到redis中,redis中有数据则直接返回;redis中无对应数据则再去访问数据库,如果数据库中也没有数据就再次发生了穿透;如果数据库中有数据则直接缓存数据并返回。


2.2.1 布隆过滤的优缺点

优点:

  • 内存占用较少,没有多余key

缺点:

  • 实现复杂
  • 存在误判可能(不同数据的hash结果可能相同)

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

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

相关文章

HTML与CSS基础(十)—— 综合项目

应用前面技术知识 完成小兔鲜儿项目设计图素材下载:链接: https://pan.baidu.com/s/1o5mWkgEfaTAA5spxMLuXEQ?pwdex7e 提取码: ex7e 一、Header 部分开发 布局分析:header布局分析:xtx-shortcut ①布局分析:xtx-shortcut ②布局分…

Hudi系列3:Hudi核心概念

文章目录Hudi架构一. 时间轴(TimeLine)1.1 时间轴(TimeLine)概念1.2 Hudi的时间线由组成1.3 时间线上的Instant action操作类型1.4 时间线上State状态类型1.5 时间线官网实例二. 文件布局三. 索引3.1 简介3.2 对比Hive没有索引的区别3.3 Hudi索引类型3.4 全局索引与非全局索引四…

数学建模-回归分析(Stata)

注意:代码文件仅供参考,一定不要直接用于自己的数模论文中国赛对于论文的查重要求非常严格,代码雷同也算作抄袭 如何修改代码避免查重的方法:https://www.bilibili.com/video/av59423231 //清风数学建模 一、基础知识 1.简介 …

不得不面对的随机MAC问题

一、现状 为了完善安全机制、保护用户隐私,各个设备厂商开发了 MAC 地址随机功能,防止用户信息泄露。随机 MAC 地址,就是一个随机生成的伪 MAC 地址,一个假 MAC 地址,使用随机 MAC 地址进行网络通信,而不是…

全网圣诞树最全完整源码下载合集【可下载】

文章目录一、全部源码打包下载:二、效果预览001-html版本 豪华动态圣诞树 抖音同款002-圣诞树灯光跟随音乐节拍一起呼吸点亮下雪动画效果代码003-圣诞树彩带飘动节日快乐效果代码004-圣诞树带音乐旋转拉伸动画效果005-python版本python取消延迟秒出图版 【全网最强无…

当FutureTask遇上DiscardPolicy,有坑

文章目录有啥坑呢?知识回顾问题触发条件问题复现问题分析问题修复扩展哈喽,你好,我是余数。今天来了解下当 FutureTask 遇上 DiscardPolicy 或 DiscardOldestPolicy 时容易掉的坑,然后分析分析问题产生的原因以及如何规避这类问题…

LVS+Keepalived+Nginx具体配置步骤

视频链接:4-6 搭建LVS-DR模式- 为两台RS配置虚拟IP_哔哩哔哩_bilibili 视频笔记链接:笔记 一、服务器与Ip约定 LVS DIP: 192.168.1.151 VIP: 192.168.1.150 Nginx1 RIP: 192.168.1.171 VIP: 192.168.1.150 Nginx2 RIP: 192.168.1.172 VIP: 192.168…

力扣 2283. 判断一个数的数字计数是否等于数位的值

题目 给你一个下标从 0 开始长度为 n 的字符串 num &#xff0c;它只包含数字。 如果对于 每个 0 < i < n 的下标 i &#xff0c;都满足数位 i 在 num 中出现了 num[i]次&#xff0c;那么请你返回 true &#xff0c;否则返回 false 。 示例 输入&#xff1a;num “1…

vue文件上传

vue文件上传 前言 今天写一篇关于文件上传的文章&#xff0c;其实对于真正工作的人来说&#xff0c;这不是很难的事&#xff0c;但对于新手来说无疑是个新技术 实现功能如下图 根据上传文件类型显示对应文件类型&#xff0c;图片直接显示&#xff0c;当然图片特可以做对应类型…

【NI Multisim 14.0原理图设计基础——参数属性设置】

目录 序言 &#x1f46c;一、参数属性设置 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI Multisim 14.0&#xff0c;打开如图所示的启动界面&#xff0c;完成初始化后&…

初始C语言-分支与循环语句

目录 一、语句 1. 什么是语句&#xff1f; C语句可分为以下五类&#xff1a; 1. 表达式语句 2. 函数调用语句 3. 控制语句 4. 复合语句 5. 空语句 2. 控制语句&#xff1a; 1. 条件判断语句也叫分支语句&#xff1a;if语句、switch语句&#xff1b; 2. 循环执行语句…

extern “C“的作用以及c/c++代码互调

一、目的相信从事嵌入开发的小伙伴肯定遇到过使用第三库的情景&#xff0c;有时候可能是C中调用C库&#xff0c;有时候可能又是C中调用C库&#xff1b;如果你遇到过&#xff0c;那你肯定知道extern "C"的作用.本篇的目的就是给大家介绍C/C互相调用的原理和实践。二、…

RK3588平台开发系列讲解(内核调试篇)CPU Hotplug 调试

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、CPU Hotplug 介绍二、CPU Hotplug 内核开关三、sysfs调试沉淀、分享、成长,让自己和他人都能有所收获!😄 📢多核系统底层驱动提供了cpu的Plugin/Unplug接口,可以实现动态调整cpu使用运行。 一、CPU Hotplu…

在 Node JS 中实现微服务架构

&#x1f4cd;简介&#x1f642; 正如我们在之前的博客“单体与微服务&#xff1a;一种实用方法”中讨论的那样。但是今天我们要在 NodeJS 中实现微服务架构。&#x1f449; 您可以使用任何技术&#xff0c;如 Spring、Python 等。但我们将使用 NodeJS 进行演示。&#x1f4cd;…

PostgreSQL下载、安装和配置使用

1&#xff09;下载 PostgreSQL官网下载&#xff1a;https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 2&#xff09;安装 双击运行安装包 选择安装目录&#xff0c;不推荐安装在C盘。 选择需要安装的服务&#xff0c;不明白是啥的全选就行&#xf…

内含JAVA简单概括和JAVA所需安装的软件和详细教程,想学习JAVA无从下手,这篇文章带你迈出第一步

本文大致概括了JAVA编程语言的简史和特点,主要介绍了JAVA开发环境安装,涉及JDK,Sublime Text IntelliJ IDEA三个软件的简单介绍,安装和使用,最后编写了第一个JAVA代码,保姆级教学,跟着文章一步步来,迈出你学习JAVA的第一步吧! 初识JAVA一.JAVA语言简介二.JAVA发展简史三.JAVA语…

通过模拟器实现APP抓包

本教程将跳过工具安装部分&#xff0c;请正确食用&#x1f609;我的环境&#xff1a;操作系统&#xff1a;win11模拟器版本&#xff1a;雷电安卓模拟器稳定版-安卓7.1(32位) V5.0.46抓包工具&#xff1a;Wireshark-Version 4.0.1抓包工具&#xff1a;charles-Version 4.6.3工具…

SpringMVC(十一):SpringMVC文件上传中要解决的问题

文章目录 SpringMVC文件上传中要解决的问题 一、中文文件名编码问题 二、文件位置存储问题

【YOLO系列】YOLOv8算法(尖端SOTA模型)

前言回顾 在这里粗略回顾一下YOLOv5&#xff0c;这里直接提供YOLOv5的整理的结构图吧 Backbone&#xff1a;CSPDarkNet结构&#xff0c;主要结构思想的体现在C3模块&#xff0c;这里也是梯度分流的主要思想所在的地方&#xff1b;PAN-FPN&#xff1a;双流的FPN&#xff0c;必…

Linux——常用命令1.

✅<1>主页&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;linux &#x1f525;<3>创作者&#xff1a;我的代码爱吃辣 ☂️<4>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<5>前言&#xff1a;Linux常用命令 目录 …