Redis实战案例6-缓存穿透及其解决案例

news2024/10/6 14:36:06

1. 缓存穿透

缓存穿透是指在缓存中查找一个不存在的值,由于缓存一般不会存储这种无效的数据,所以每次查询都会落到数据库上,导致数据库压力增大,严重时可能会导致数据库宕机。

解决方案:

方法一:缓存空对象
会带来内存消耗,但是可以设置TTL缓解;
而对于短期的不一致,是因为在给缓存中设置null数据时,可能此时数据库更新该id的数据,用户在TTL的时期内一直查到的是null,这就造成了短期的不一致;
对于不一致可以采取数据库更新,缓存也进行对应的删除和添加,可以进行解决;

在这里插入图片描述
在这里插入图片描述

方法二:布隆过滤
布隆过滤器判断存在时,是可能存在的并不是一定存在

在这里插入图片描述

在这里插入图片描述
布隆过滤器简单介绍:
Redis布隆过滤器是一种基于位数组的数据结构,其原理如下:

  1. 由一个位数组和若干个哈希函数构成。

  2. 初始时,所有位数组的值均为0。当加入一个元素时,使用若干个哈希函数分别对其进行计算,并将计算结果所对应的位数组值设为1。

  3. 当检查一个元素是否存在于集合中时,同样使用若干个哈希函数计算该元素,如果对应的位数组值均为1,则可以认为该元素可能存在于集合中,如果其中任意一个位数组的值为0,则肯定不存在于集合中。

  4. 由于哈希函数可能产生哈希碰撞,即不同元素计算出的哈希值相同,因此布隆过滤器无法准确的确定集合中是否存在一个元素,但可以保证如果一个元素被判定不存在,那么它一定不存在,如果判定它存在,那么它可能存在于集合中。

  5. 布隆过滤器具有非常高的存储效率和查询效率,但存在误判率较高的问题,因此通常作为集合判重的辅助手段,不能作为唯一的判重手段。

2. 解决商铺查询的缓存穿透问题

在这里插入图片描述

所以查询商铺的代码应该修改为;

这里要做缓存穿透处理,是有意缓存null的,所以要对null多做一次判断
在这里插入图片描述

@Override
public Result queryById(Long id) {
    String key = CACHE_SHOP_KEY + id;
    //1. 从Redis中查询商铺缓存
    String shopJson = stringRedisTemplate.opsForValue().get(key);
    //2. 判断是否存在
    if(StrUtil.isNotBlank(shopJson)){
        //3. 存在,直接返回
        Shop bean = JSONUtil.toBean(shopJson, Shop.class);
        return Result.ok(bean);
    }
    // 这里要先判断命中的是否是null,因为是null的话也是被上面逻辑判断为不存在
	// 这里要做缓存穿透处理,所以要对null多做一次判断,如果命中的是null则shopJson为""
    if("".equals(shopJson)){
        return Result.fail("店铺不存在");
    }
    //4. 不存在,根据id查询数据库
    Shop byId = getById(id);
    if(byId == null) {
        //5. 不存在,将空值写入redis缓存,以便下次继续查询缓存时,如果还是查询空值可以直接返回false信息
        stringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);
        return Result.fail("店铺不存在");
    }
    //6. 存在,写入Redis
    stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(byId), CACHE_SHOP_TTL, TimeUnit.MINUTES);
    //7. 返回
    return Result.ok(byId);
}

总结

缓存空对象和布隆过滤器都是被动解决方案,实际系统应该增加主动解决方法。

  1. 增强id的复杂度
  2. 做好数据的基础格式校验
  3. 加强用户权限校验
  4. 做好热点参数的限流

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

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

相关文章

【Python】异常处理 ② ( 捕获所有类型的异常 | 默认捕获所有类型异常 | 捕获 Exception 异常 )

文章目录 一、Python 默认捕获所有类型异常1、默认捕获所有类型异常 - 无法获取异常类型2、代码实例 - 默认捕获所有类型异常 二、Python 捕获所有类型异常 - 捕获 Exception 异常1、捕获 Exception 类型异常 - 可获取异常类型2、代码实例 - 捕获 Exception 异常 一、Python 默…

猴子都能听懂的 从 0 到 1 设计一个网络

标题开玩笑了哈,大家不要介意,就是说本文真的超级大白话! 话不多说,开始整活! 你很爱玩电脑游戏,你买了一台电脑,就一个人自己玩,也不需要和谁沟通,不需要与别人联机&am…

数据库判断分解的无损连接性

例题 关系模式R(ABCDE),F{A->C,C->D,B->C,DE->C,CE->A} 若分解成R1(AD)R2(AB)R3(BC)R4(CDE)R5(AE)判断是否具有无损连接性 画出如下表格如第一行:AD,那么在A,D的地方填入,i表…

C++ Primer 第9章顺序容器

9.1 顺序容器概述 确定使用哪种顺序容器 通常使用vector是最好的选择 9.2 容器库概述(本节所有容器均适用) 对容器可以保存的元素类型的限制 有些类没有提供默认构造函数,我们可以定义一个这种类型对象的容器,但我们在构造这种容器时不能只传递给它一个数目参数. 9.2.1 迭…

MySQL进阶SQL语句(二)

MySQL进阶SQL语句(二) 一、MySQL进阶SQL语句1.1 连接查询1.2 CREATE VIEW视图,可以被当作是虚拟表或存储查询1.3 UNION 联集1.4 CASE1.5 空值(NULL) 和 无值() 的区别1.6 正则表达式 二、存储过程2.1 存储过程定义2.2 存储过程的优点2.3 存储…

(秋招)闭环检测流程回顾

vins中的闭环检测和重定位 回环检测的关键就是如何有效检测出相机曾经经过同一个地方,这样可以避免较大的累积误差,使得当前帧和之前的某一帧迅速建立约束,形成新的较小的累积误差。由于回环检测提供了当前数据与所有历史数据的关联&#xf…

快速搭建node.js新项目和大事件后台项目

声明:参考https://zhuanlan.zhihu.com/p/464271490?utm_id0 参考:https://brucecai55520.gitee.io/bruceblog/notes/nodejs/ev_api_server.html#_1-4-%E5%88%9D%E5%A7%8B%E5%8C%96%E8%B7%AF%E7%94%B1%E7%9B%B8%E5%85%B3%E7%9A%84%E6%96%87%E4%BB%B6%E5…

Linux文件系统的缓冲区问题

目录 一.什么是缓冲区? 1.1实验案例1: 情况1:运行该程序 情况2:此时我将该程序运行的结果输出重定向到一个文本文件中: 二.为什么要有缓冲区? 于是引出了缓冲区的刷新策略: 三.缓冲区在哪…

【学习笔记】 科目一之计算题篇

【学习笔记】 科目一之计算题篇 三点估算PERT 三点估算期望:(悲观+4*最可能+乐观)/6三点估算标准差:(悲观-乐观)/6正态分布四个数:34.1%,13.65%,2.1%,0.15%决策树 分叉计算注意:成本越小越好投资回报:收益-投入投资回报率(ROI)=收益-投入/投入投资回收期 静态回…

算法--PageRank

概念 PageRank是Google提出的算法,用于衡量特定网页相对于搜索引擎索引中的其他网页而言的重要程度。是Google创始人拉里佩奇和谢尔盖布林于1997年创造的PageRank实现了将链接价值概念作为排名因素。 GOOGLE PageRank并不是唯一的链接相关的排名算法,而…

如何提升 MySQL 的查询速度?

💂 个人网站:【海拥】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 目录 前言优化数据库结构1 使…

QT(一) 安装 QT(二)

第一章 : Qt 安装 下载地址安装 打开 cmd 运行镜像 : qt-unified-windows-x64-4.6.0-online.exe --mirror https://mirrors.aliyun.com/qt Hello 因为是qmake 所以是.proCtrl R 直接运行 第二章 GUI程序设计基础 main文件 *.ui : 有UI设计器自动生成…

【工具】Spring 历史官方文档理解(持续更新)

文章目录 [1] Spring Framework 5.2.24CoreAOP 概念AspectJoin pointAdvicePointcutIntroductionTarget objectAOP proxyWeaving Spring AOPAspectJ官方 demo 学习 Pointcut 表达式官方 demo 学习 Advice 声明官方 demo 学习 Introductions (接口拓展)AO…

0004Java程序设计-SSM+JSP医院挂号系统

摘 要 医院挂号,一直以来就是困扰医院提高服务水平的重要环节,特别是医疗水平高、门诊访问量高的综合型医院,门诊拥挤就成了普遍现象。因此,本文提出了医院挂号系统。预约挂号,是借助信息化的技术,面向全社…

代码随想录二刷 day32 | 贪心之 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II

这里写目录标题 122.买卖股票的最佳时机II55. 跳跃游戏45.跳跃游戏II 122.买卖股票的最佳时机II 题目链接 解题思路: 首先要清楚两点: 只有一只股票!当前只有买股票或者卖股票的操作 想获得利润至少要两天为一个交易单元。 代码如下&#x…

【Unity每日一记】时间Time类-做时间管理大师

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

独立开发变现周刊(第92期):创建一个年收入350万美元的小工具,1000万至1500万美元出售...

分享独立开发、产品变现相关内容,每周五发布。 目录 1、Vercel AI: 使用React, Svelte和Vue快速构建 AI 驱动的应用2、Novel:AI自动补全功能的Notion风格所见即所得编辑器3、Notionbase: 通过Notion轻松建立你的AI聊天机器人4、Plasmo: 一款功能强大的浏…

Python入门教程+项目实战-14.1节-程序实战-二分查找算法

目录 14.1.1 理解函数类型 14.1.2 函数的定义 14.1.3 函数的形参,实参,以及调用 14.1.4 函数的返回值 14.1.5 函数的命名规范 14.1.6 知识要点 14.1.7 系统学习python 14.1.1 理解函数类型 在Python中,函数也是一种数据类型。在理解函…

C++——详解类模板与友元函数

纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。 💬文章目录 类模板与友元函数1️⃣非模板友元函数2️⃣约束模板友元函数3️⃣非约束模板友元函数 类模板与友元函数 模板类的友元函数有三类: …

Qt/C++编写手机版本视频播放器和Onvif工具(可云台和录像)

一、前言 用Qtffmpeg写播放器很多人有疑问,为何不用Qt自己的多媒体框架来写,最重要的原因是Qt自带的目前都依赖具体的本地解码器,如果解码器不支持,那就是歇菜的,最多支持个MP4格式,而且在手机上也都是支持…