redis缓存穿透

redis缓存穿透

模拟一个缓存穿透的环境:

    • redis缓存穿透
      • 1. 准备一个GET请求并且在第一次访问的时候将数据写入缓存
      • 2. 再次访问的时候首先判断缓存是否命中
      • 3. 命中了直接返回,未命中重建缓存
      • 1. 缓存空对象
      • 2. 布隆过滤器

1. 准备一个GET请求并且在第一次访问的时候将数据写入缓存

        // 首先从缓存中获取数据Object articleObj = redisTemplate.opsForValue().get(ARTICLE_KEY + id);// 拿到缓存了就直接返回if (Objects.nonNull(articleObj)){String articleJSON = (String) articleObj;ApArticle article = JSON.parseObject(articleJSON, ApArticle.class);return ResponseResult.okResult(article);}// 通过数据库获取文章数据ApArticle article = getById(id);// 重建缓存redisTemplate.opsForValue().set(ARTICLE_KEY + id, JSON.toJSONString(article),ARTICLE_EXPIRED);// 返回获得的文章数据return ResponseResult.okResult(article);

2. 再次访问的时候首先判断缓存是否命中

3. 命中了直接返回,未命中重建缓存

什么事缓存穿透?
缓存穿透其实是一种攻击性的行为。其实是接口访问一个缓存和数据数据库中都不存在的数据,这个数据每次都会去请求数据库,如果没有进行处理的话,恶意的请求会对数据库造成极大的压力。

模拟一个500并发量的请求,单接口的响应耗时已经达到了1500毫秒
在这里插入图片描述
解决缓存穿透的问题:

1. 缓存空对象

在数据没有命中缓存的时候这个请求会直接的打到后端数据库上,
那么可以对这个没有命中的数据也对应的缓存到redis中,当请求再次来临的时候就不会去访问数据库
缺点:可能会浪费redis大量的内存,并且可能会出现不一致的问题(例如第一次id为2的没有数据,被缓存了空数据,然而后续2插入了数据,再次访问就会有不一致的问题)
优点:实现简单

2. 布隆过滤器

布隆过滤器
布隆过滤器本质上是一个bitmap
不能保证存在,但是可以保证一定不存在
guava的工具包为我们做了布隆过滤器的实现

  1. 添加guava工具包
        <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId></dependency>
  1. 创建布隆过滤器的Bean并且初始化布隆过滤器。需要使用init方法对布隆过滤器进行数据的初始化,否则布隆过滤器中没有数据,所有的请求来临都会被拒绝掉。
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.model.article.pojos.ApArticle;
import org.apache.hbase.thirdparty.com.google.common.hash.BloomFilter;
import org.apache.hbase.thirdparty.com.google.common.hash.Funnels;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;
import static com.heima.model.constant.Constant.BLOOM_FILTER_EXPECTED_SIZE;
import static com.heima.model.constant.Constant.BLOOM_FILTER_FALSE_POSITIVE_RATE;@Configuration
public class BloomFilterConfig {@Autowiredprivate ApArticleMapper apArticleMapper;public final BloomFilter<Long> bloomFilter;public BloomFilterConfig(){// 预期元素数量,误判率this.bloomFilter = BloomFilter
//                .create(Funnels.unencodedCharsFunnel(),BLOOM_FILTER_EXPECTED_SIZE,BLOOM_FILTER_FALSE_POSITIVE_RATE);.create(Funnels.longFunnel(),BLOOM_FILTER_EXPECTED_SIZE,BLOOM_FILTER_FALSE_POSITIVE_RATE);}@PostConstructpublic void init(){BloomFilter<String> longBloomFilter = bloomFilter();// 查询缓存,并且写入到布隆过滤器Set<String> keys = redisTemplate.keys("KEYS article:id:*");keys.forEach(longBloomFilter::put);}@Beanpublic BloomFilter<Long> bloomFilter(){// 预期元素数量,误判率return bloomFilter;}}
  1. 注入布隆过滤器进行判断。
        // 判断这个id是不是在布隆过滤器中boolean mightContain = bloomFilter.mightContain(ARTICLE_KEY + id);// 不存在直接返回if (!mightContain){return ResponseResult.okResult();}// 首先从缓存中获取数据Object articleObj = redisTemplate.opsForValue().get(ARTICLE_KEY + id);// 拿到缓存了就直接返回if (Objects.nonNull(articleObj)){String articleJSON = (String) articleObj;ApArticle article = JSON.parseObject(articleJSON, ApArticle.class);return ResponseResult.okResult(article);}// 通过数据库获取文章数据ApArticle article = getById(id);// 重建缓存if (Objects.nonNull(article)){redisTemplate.opsForValue().set(ARTICLE_KEY + id, JSON.toJSONString(article),ARTICLE_EXPIRED,TimeUnit.SECONDS);}// 返回获得的文章数据return ResponseResult.okResult(article);

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

avi怎么转mp4?

avi怎么转mp4&#xff1f;如今市面上涌现了各种多样的视频格式&#xff0c;其中AVI作为一种音频视频交错格式&#xff0c;虽然使用较少但相对常见。它的优点在于占用空间较小&#xff0c;但画面质量并不是很出色。然而&#xff0c;AVI格式也存在一个明显的缺点&#xff0c;即兼…

柯桥专升本学校,自考本科文凭的价值如何?

自考本科文凭的价值如何&#xff1f; 自考本科学历是通过独立学习和考试获得的一种本科学历。对于自考本科学历的价值&#xff0c;很多人感到困惑&#xff0c;那么究竟自考本科学历有多大的价值呢? 首先&#xff0c;在就业市场上&#xff0c;自考本科学历具有一定的竞争力。随…

VBA技术资料MF77:组合所选范围中的所有形状

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…

横屏签字板手写签名并旋转90°转为横屏显示base64

手写签名并旋转90转为横屏显示base64 base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAApsAAAF3CAYAAADq/IAAAAAAAXNSR0IArs4c6QAAIABJREFUeF7t3W3MPlldH/CvwLK7wEKNoiABZLvYiBqIdJGnQlor9gVBaAtJmzQsoI2wgKD4hqVNmrD7ohWhPFRSIgaKO0XTS8AVLb4AIVtFnaSiMPSktxoyVVWFxAF…

我的云栖大会之旅:见证云计算创新的15年

云栖大会&#xff0c;曾经是一次不可思议的科技之旅&#xff0c;却如今已见证了我对云计算世界的15年关注和发展。第一次踏上云栖大会之旅&#xff0c;我记得是在2009年。那时的云计算还是一个新生事物&#xff0c;而云栖大会正是其中的奠基石。 我清楚地记得那个炎热的夏天&am…

OpenCV标定演示,及如何生成标定板图片

标定的程序在官方的源码里有&#xff0c; opencv-4.5.5\samples\cpp\tutorial_code\calib3d\camera_calibration 很多小白不知道怎么跑起来&#xff0c;这个也怪OpenCV官方&#xff0c;工作没做完善&#xff0c;其实的default.xml是要自己手动改的&#xff0c;输入的图片也要…

【QT】鼠标常用事件

新建项目 加标签控件 当鼠标进去&#xff0c;显示【鼠标进入】&#xff0c;离开时显示【鼠标离开】 将QLable提升成自己的控件&#xff0c;然后再去捕获 添加文件 改继承的类名 提升类 同一个父类&#xff0c;可以提升 效果 现在代码就和Qlabel对应起来了。 在.h中声明&…

Linux———— 运算命令

Shell与其他编程语言一样&#xff0c;支持多种类型的运算符&#xff0c;包括&#xff1a; 算术运算符&#xff1a;用于执行数学运算&#xff0c;例如加法、减法、乘法和除法。 关系运算符&#xff1a;用于比较两个值之间的关系&#xff0c;例如相等、大于、小于等。 布尔运算…

FPGA 如何 固化程序到 FLASH中

1、导出Hardware 2、导出bit文件 3、打开SDK 4、 点击Ok 5、创建工程 6、 输入工程名称&#xff1a;guhua 7、选择 Zynq FSBL 8、单击 guhua、然后点击 build 点击&#xff1a;build all 9、 右键之后&#xff0c;点击&#xff1a;Creat Boot Image 10、点击 Cr…

项目解读_v2

1. 项目介绍 如果使用task2-1作为示例时&#xff0c; 运行process.py的过程中需要确认 process调用的是函数 preprocess_ast_wav2vec(wav, fr) 1.1 任务简介 首个开源的儿科呼吸音数据集&#xff0c; 通过邀请11位医师标注&#xff1b; 数字听诊器的采样频率和量化分辨率分…

大厂面试题-网络四元组

四元组&#xff0c;简单理解就是在TCP协议中&#xff0c;去确定一个客户端连接的组成要素&#xff0c;它包括源 IP地址、目标IP地址、源端口号、目标端口号。 正常情况下&#xff0c;我们对于网络通信的认识可能是这样(如图)。 服务端通过Server Socket建立一个对指定端口号…

商城性能测试LoadRunner快速上手教学

软件介绍 Virtual User Generator &#xff0c;记录用户流程并创建一个自动化性能测试脚本Controller&#xff0c;单一控制点&#xff0c;轻松、有效地控制所有Vuser&#xff0c;执行期间监控场景性能Analysis&#xff0c;生成性能测试报告&#xff0c;以图表形式呈现。 由于…

UE5使用Dash插件实现程序化地形场景制作

目录 0 dash下载后激活 1 初步使用 2 导入bridge的资产路径 3 练习成果 4 参考链接 0 dash下载后激活 1 初步使用 Dash插件点击蓝色的A&#xff0c;可以使用。 通过输入不同提示命令&#xff0c;来激活不同的功能。 2 导入bridge的资产路径 这里需要注意是UAsserts…

解决Linux Debian12系统中安装VirtualBox虚拟机无法使用USB设备的问题

Debian12系统中安装VirtualBox&#xff0c;再VirtualBox虚拟机中无法使用 USB设备。如下图所示&#xff1a; 解决方法如下&#xff1a; 1.安装 Virtualbox增强功能。如下图所示&#xff1a; 2.添加相关用户、用户组&#xff08; Virtualbox 装完成后会有 vboxusers 和 vboxs…

Vue:实现输入vue组件名称,就可以从网页上加载出组件

作者:CSDN @ _乐多_ 本文记录了使用动态组件实现在网页上输入vue组件名称,就可以从网页上直接加载组件的功能的代码。 实现效果如下所示, 在许多Vue.js应用中,我们有大量的组件,但并不是每个组件都需要在应用初始化时加载。动态加载组件的好处包括: 减小初始加载时间:…

Android页面周期、页面跳转

1.什么是Activity&#xff1f; Activity是Android的四大组件之一&#xff0c;它是一种可以包含用户界面的组件&#xff0c;主要用于和用户进行交互。Activity用于显示用户界面&#xff0c;用户通过Activity交互完成相关操作&#xff0c;一个APP允许有多个Activity。 2.Activi…

职业规划:如何成为年薪80W+的Salesforce项目经理?

Salesforce项目经理负责监督各种Salesforce云和端到端Salesforce项目&#xff0c;首要任务是确保项目成功&#xff0c;并在预算范围内按时交付。Salesforce项目经理的薪资是不断增长的Salesforce经济中的热门话题。 Salesforce项目经理的职责 项目经理的职业发展更多地关注经验…

JS 去除字符串中所有标点符号

直接上代码了 var str 这是《书》中的一段&#xff0c;两段文字。; var new_str str.replace(/[:_.~!#$%^&*() \ <>?"{}|, \/ ; \\ [ \] ~&#xff01;#&#xffe5;%……&*&#xff08;&#xff09;—— \ {}|《》&#xff1f;&#xff1a;“”【】、&a…

Goby 漏洞发布| Cisco IOS XE ebui_wsma_http 接口权限绕过漏洞(CVE-2023-20198)

漏洞名称&#xff1a; Cisco IOS XE ebui_wsma_http 接口权限绕过漏洞&#xff08;CVE-2023-20198&#xff09; English Name&#xff1a; Cisco IOS XE ebui_wsma_http API Permission Bypass Vulnerability (CVE-2023-20198) CVSS core: 10 影响资产数&#xff1a; 307282…

分享一下微信小程序里怎么开店

如何在微信小程序中成功开店&#xff1a;从选品到运营的全方位指南 一、引言 随着微信小程序的日益普及&#xff0c;越来越多的人开始尝试在微信小程序中开设自己的店铺。微信小程序具有便捷、易用、即用即走等特点&#xff0c;使得开店门槛大大降低。本文将详细介绍如何在微…