【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)

文章目录

  • 🍔什么是缓存穿透
  • 🎄解决办法
    • ⭐缓存空值处理
      • 🎈优点
      • 🎈缺点
      • 🎍代码实现
    • ⭐布隆过滤器
      • 🎍代码实现

在这里插入图片描述

🍔什么是缓存穿透

缓存穿透是指在使用缓存机制时,大量的请求无法从缓存中获取到结果,导致请求都要直接访问后端存储系统,从而增加了系统的负载和响应时间。

通常的缓存机制是将请求的结果缓存在内存或其他高速存储介质中,当相同的请求再次到达时,可以直接从缓存中获取结果,避免了从后端存储系统中读取数据的开销。

然而,在缓存穿透的情况下,由于大量请求所对应的数据在缓存中不存在,每个请求都需要直接访问后端存储系统。这可能是因为恶意请求、频繁的随机查询或者查询不存在的数据等原因。

缓存穿透可能导致以下问题:

  • 性能下降:由于大量的请求都要直接访问后端存储系统,系统的响应时间会显著增加,导致性能下降。
  • 增加负载:后端存储系统承受了大量无效请求的压力,增加了系统的负载,可能导致后端存储系统的性能问题。
  • 安全风险:缓存穿透可能为恶意请求提供了一种绕过缓存机制直接访问后端存储系统的途径,可能导致安全漏洞或数据泄露。

🎄解决办法

  1. 缓存空值处理:对于不存在的数据,也将其缓存起来,但缓存的值为空,这样下次再有相同的请求到达时,可以直接返回空结果,避免对后端存储系统的重复查询。
  2. 布隆过滤器(Bloom Filter):使用布隆过滤器可以快速判断请求所对应的数据是否存在于缓存中,从而减少对后端存储系统的无效查询。

请添加图片描述

⭐缓存空值处理

请添加图片描述

🎈优点

实现简单,维护方便

🎈缺点

  • 额外的内存消耗
  • 可能造成短期数据的不一致

🎍代码实现

在这里插入图片描述

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Resourceprivate CacheClient cacheClient;@Overridepublic Result queryById(Long id) {String key=CACHE_SHOP_KEY+":"+id;//从redis中查询商铺缓存String shopJson=stringRedisTemplate.opsForValue().get(key);//判断是否存在if(StrUtil.isNotBlank(shopJson)){    //isNotBlank只有传入的是 字符串 的情况下,才返回true,否则返回false//存在,直接返回Shop shop= JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}//判断命中的是否是空值//因为上面isNotBlank判断了有值的情况了,下面需要判断的就2种情况 null 和 空字符串if(shopJson!=null){//不为null,那么为空字符串return Result.fail("店铺不存在!");}//不存在,根据id查询数据库Shop shop = this.getById(id);//不存在,返回错误信息if (shop == null) {//将空值写入到redisstringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);return Result.fail("店铺不存在!");}//存在,写入到redis里面stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);//返回return Result.ok(shop);
}

⭐布隆过滤器

请添加图片描述
布隆过滤器是一种空间效率高、适合大规模数据的概率型数据结构,用于判断一个元素是否可能存在于一个集合中。布隆过滤器由一个位数组和多个哈希函数组成。其核心思想是通过多个哈希函数对输入元素进行映射,将元素映射到位数组的多个位置上,从而实现元素的快速查找。

假设布隆过滤器使用一个长度为 m 的位数组和 k 个独立的哈希函数,初始时所有位都置为 0。当要插入一个元素时,将该元素经过 k 个哈希函数得到的 k 个哈希值作为索引,在位数组中将这 k 个位置的值置为 1。当要查询一个元素时,同样将该元素经过 k 个哈希函数得到的 k 个哈希值作为索引,并检查对应的位数组位置是否都为 1,若有任何一个位置为 0,则可以确定该元素不存在于集合中;若都为 1,则该元素可能存在于集合中。

布隆过滤器的优势在于具有较高的空间效率和查询效率,适合大规模数据的情况。由于使用了多个哈希函数,可以有效减少冲突的概率,降低误判率。然而,布隆过滤器也存在一定的缺陷,即可能出现误判(即判断某个元素存在于集合中,但实际上并不存在),这是由于不同元素经过哈希函数映射后的索引可能存在冲突。因此,在使用布隆过滤器时需要权衡误判率和空间利用率。

总的来说,布隆过滤器通过位数组和多个哈希函数实现了高效的元素判断,是一种适合大规模数据场景下的概率型数据结构

🎍代码实现

实现引入依赖

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>29.0-jre</version></dependency>

配置启动类
在这里插入图片描述

编写核心代码

在这里插入图片描述

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Autowiredprivate BloomFilter<Long> bloomFilter;@Overridepublic Result queryById(Long id) {String key = CACHE_SHOP_KEY + ":" + id;// 使用布隆过滤器判断缓存键是否存在if (!bloomFilter.mightContain(id)) {// 缓存键不存在,直接返回错误信息return Result.fail("店铺不存在!");}// 从redis中查询商铺缓存String shopJson = stringRedisTemplate.opsForValue().get(key);// 判断是否存在if (StrUtil.isNotBlank(shopJson)) {// 存在,直接返回Shop shop = JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}// 不存在,根据id查询数据库Shop shop = this.getById(id);// 不存在,返回错误信息if (shop == null) {// 将空值写入到redisstringRedisTemplate.opsForValue().set(key, "", CACHE_SHOP_TTL, TimeUnit.MINUTES);// 将缓存键加入布隆过滤器bloomFilter.put(id);return Result.fail("店铺不存在!");}// 存在,写入到redis里面stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);// 将缓存键加入布隆过滤器bloomFilter.put(id);// 返回return Result.ok(shop);}

在这里插入图片描述

更加详细的布隆过滤器讲解,请参考我的Redis专栏Redis专栏里面讲解布隆过滤器的文章

在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!

在这里插入图片描述

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

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

相关文章

docker-compose介绍和用法

docker-compose介绍和用法详解 1、docker-compose介绍2、docker-compose build3、docker-compose down4、docker-compose up -d 1、docker-compose介绍 Docker Compose是一个用于快速配置多个Docker容器的工具。它是一个定义和运行多容器的Docker应用工具&#xff0c;通过YAML…

设计模式-GOF对各个模式的定义

以下内容是对设计模式之父GOF的著作《设计模式——可复用面向对象软件的基础》定义的摘抄 1 抽象工厂 意图 提供一个接口以创建一系列相关或相互依赖的对象&#xff0c;而无须指定它们具体的类。 适用性 在以下情况下使用抽象工厂模式&#xff1a; 一个系统要独立于它的产…

docker基本命令

1.docker命令图解 2. 从仓库拉取镜像 #下载最新版 docker pull nginx # 镜像名:版本名&#xff08;标签&#xff09; docker pull nginx:1.20.1docker rmi 镜像名:版本号/镜像id3. 容器启动及停止 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] docker run [设置项] 镜…

栈——OJ题

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、最小栈1、题目讲解2、思路讲解3、代码实现 二、栈的压入、弹出序列1、题目讲解2、思路讲解…

Windows使用VNC Viewer远程桌面Ubuntu【内网穿透】

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…

系列十、存储引擎

一、存储引擎 1.1、概述 大家可能没有听说过存储引擎&#xff0c;但是一定听过引擎这个词&#xff0c;引擎就是发动机&#xff0c;是一个机器的核心组件。 比如&#xff0c;对于舰载机、直升机、火箭来说&#xff0c;它们都有各自的引擎&#xff0c;引擎是它们最为核心的组件。…

【NI-RIO入门】使用LabVIEW进行数据采集测量

于ni kb摘录 选择合适的编程模式 CompactRIO系统具有至少两个用户可选模式。某些CompactRIO型号具有附加的用户可选模式&#xff0c;可以在实时NI-DAQmx中进行编程。请参考本文以判断您的CompactRIO是否能够使用实时NI-DAQmx。将目标添加到项目后&#xff0c;将提示您选择要使…

Jmeter接口测试断言

一、响应断言 对服务器的响应接口进行断言校验&#xff0c;来判断接口测试得到的接口返回值是否正确。 二、添加断言 1、apply to&#xff1a; 通常发出一个请求只触发一个请求&#xff0c;所以勾选“main sampie only”就可以&#xff1b;若发一个请求可以触发多个服务器请…

【C++】标准库中的string类

目录 一、介绍 二、常用接口 1.构造函数和赋值操作 2.string类对象的容量操作 3.string类对象的访问及遍历操作 4.string类对象的修改操作 5.string类非成员函数 放在最后 一、介绍 在C中&#xff0c;std::string 是标准库提供的字符串类。它属于 <string> 头文件…

(已解决)如何使用matplotlib绘制小提琴图

网上很多人使用seaborn绘制小提琴图&#xff0c;本人暂时不想学新的东西&#xff0c;就是懒。本文介绍如何使用matplotlib绘制小提琴图&#xff0c;很多其他博客只是使用最简单的语法&#xff0c;默认小提琴颜色会是蓝色&#xff0c;根本改不了。本文使用了一点高级的用法&…

干涉光学测试导论

1.用于光学测试的基本干涉仪 2。相移干涉术 3。专业光学测试 4。长波长干涉术 5。非球面试验 6。表面微观结构的测量 7。绝对测量 8。结束语 第1部分-光学测试用基本干涉仪 (1)双光束干涉 (2)菲佐干涉仪和特维曼-格林干涉仪 (3)测试平面和球面的基本技术 (4)球面的基本…

【C语言】cache和程序访问的局部性对程序性能的影响

文章目录 1&#xff0e;源程序比较其性能影响2&#xff0e;内存分配&#xff08;1&#xff09;静态存储区&#xff08;static&#xff09;&#xff1a;&#xff08;2&#xff09;栈区&#xff08;stack&#xff09;&#xff1a;&#xff08;3&#xff09;堆区&#xff08;heap&…