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

news2024/9/22 23:33:21

文章目录

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

在这里插入图片描述

🍔什么是缓存穿透

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

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

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

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

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

🎄解决办法

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

请添加图片描述

⭐缓存空值处理

请添加图片描述

🎈优点

实现简单,维护方便

🎈缺点

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

🎍代码实现

在这里插入图片描述

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {


    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private CacheClient cacheClient;

    @Override
    public 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) {
            //将空值写入到redis
            stringRedisTemplate.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 {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private BloomFilter<Long> bloomFilter;

    @Override
    public 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) {
            // 将空值写入到redis
            stringRedisTemplate.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.coloradmin.cn/o/1311511.html

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

相关文章

Redis高级特性解析:持久化、主从复制与哨兵机制全面探讨

Redis持久化 RDB快照&#xff08;snapshot&#xff09; 在默认情况下&#xff0c; Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。 你可以对 Redis 进行设置&#xff0c; 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时&#xff0c; 自动保存…

bugkuctf web随记wp

常规思路&#xff1a; 1&#xff0c;源码2&#xff0c;抓包3&#xff0c;御剑dirsearch扫后台检查是否有git文件未删除4&#xff0c;参数 本地管理员&#xff1a;1&#xff0c;cu看源码&#xff0c;sci看源码有一串东西2&#xff0c;base64解码后是test123猜测是密码3&#x…

IDEA中显示方法、类注释信息

目录 一、IDEA测试版本及环境二、操作步骤2.1 鼠标悬停在某一个方法上&#xff0c;从而显示方法的注释信息2.2 调用方法时同步显示方法注释信息2.3 在new一个对象时&#xff0c;这个对象有很多重载的构造方法&#xff0c;想要重载的构造函数都显示出来 一、IDEA测试版本及环境 …

WPF仿网易云搭建笔记(6):Style进阶详解

文章目录 专栏和Gitee仓库前言Style简单使用样式字典全局样式局部全局样式全局样式穿透 专栏和Gitee仓库 WPF仿网易云 Gitee仓库 WPF仿网易云 CSDN博客专栏 前言 WPF想要批量设置样式属性&#xff0c;一共有3个方法 Style样式Template控件模板DataTemplate数据模板 WPF 零基础…

聚观早报 |iOS17.3引入设备被盗保护;iPhone16或调整设计

【聚观365】12月14日消息 iOS17.3引入设备被盗保护 iPhone16或调整设计 马斯克星链网络使用量飙升 华为鸿蒙智行App正式上线 特斯拉人形机器人Optimus二代上线 iOS17.3引入设备被盗保护 苹果向iPhone用户推送了iOS17.3开发者预览版Beta更新&#xff0c;本次更新距离上次发…

JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回收器进行调优

通过 gceasy工具对生成的 GC 日志进行分析 这里使用的 JDK 版本为 JDK8&#xff01; 在分析 GC 日志时&#xff0c;可以同时采用多种工具&#xff08;Arthas、gceasy、JVM 连接 Graphana 监控&#xff09;进行分析&#xff0c;避免某种工具分析不准确 gceasy 每个月只可以免费…

激光炸弹

title: 激光炸弹 date: 2023-12-14 19:42:59 tags: 前缀和 categories: 算法进阶指南 题目链接 − − > --> −−> 传送门 题目大意 思路 代码 #include<bits/stdc.h> #define fi first #define se second #define pb push_back #define sz size() #define …

mac python安装grpcio以及xcode升级权限问题记录

问题1: ERROR: Could not build wheels fol grpcio, which is required to install pyproject.toml-based projects pip3 install --no-cache-dir --force-reinstall -Iv grpcio1.41.0 # (我这里是降级安装的) 问题2: fatal error: ‘stdio.h’ file not found 25 | #include …

@德人合科技——天锐绿盾|电脑文件防止泄密|文件、文档、图纸、源代码等透明加密保护,防泄密软件系统

德人合科技——天锐绿盾提供了一种企业办公电脑文件防止泄密的解决方案&#xff0c;该方案对文件、文档、设计图纸、源代码等进行了透明加密保护。 pc访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 透明加密是一种保护文…

【Mars3d】关于locationBar等控件的css样式冲突处理问题

【Mars3d】关于locationBar等控件的css样式冲突处理问题 问题场景&#xff1a; 1.通过代码加载new mars3d.control.Zoom(或者通过地球map初始化配置 option.control {加载放大缩小工具控件的时候&#xff0c;出现图标的样式冲突效果&#xff1a; 2.sceneModePicker&#xf…

电脑开机出现:CLIENT MAD ADDR (网卡启动系统)的解决办法

文章目录 前言步骤1、确定情况2、对症下药——关闭网卡启动 补充1、关于BIOS2、关于PXE 前言 最近给旧电脑重装系统安了下开发环境和常用软件啥的&#xff0c;之前还好好启动的电脑&#xff0c;开机突然需要额外加载一个页面&#xff0c;虽然最后正常启动了不影响使用&#xf…

微信小程序uniapp记住密码

记住密码功能 在请求登录接口成功后&#xff0c;我们需要判断用户是否勾选记住密码&#xff0c;如果是&#xff0c;则将记住密码状态、账号信息存入本地。 下次登录时&#xff0c;获取本地的记住密码状态&#xff0c;如果为true则获取本地存储的账号信息&#xff0c;将信息回填…

构建外卖小程序:技术代码实践

在这个数字化的时代&#xff0c;外卖小程序已经成为餐饮业的一项重要工具。在本文中&#xff0c;我们将通过一些简单而实用的技术代码&#xff0c;向您展示如何构建一个基本的外卖小程序。我们将使用微信小程序平台作为例子&#xff0c;但这些原理同样适用于其他小程序平台。 …

供应链安全应该掌握哪些呢

整理了供应链安全相关的内容&#xff0c;涵盖了普及应用安全、信息安全意识的内容&#xff0c;这些内容可以面向企业全部员工进行讲解。后面包括了面向开发人员、测试人员、安全人员的内容&#xff0c;包括应用安全开发、供应链安全。面向架构人员的架构安全内容&#xff0c;后…

每日一题SQL

以下题目来源微信公众号【SQL数据库开发】 1、编写一个 SQL 查询来实现分数排名。如果两个分数相同&#xff0c;则两个分数排名&#xff08;Rank&#xff09;相同。请注意&#xff0c;平分后的下一个名次应该是下一个连续的整数值。换句话说&#xff0c;名次之间不应该有“间隔…

Django、Echarts异步请求、动态更新

前端页面 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>echarts示例</title> <script src"jquery.min.js"></script><script type "text/javascript" src "echarts.m…

持续集成交付CICD:Jenkins使用基于SaltStack的CD流水线下载Nexus制品

目录 一、理论 1.salt常用命令 二、实验 1.SaltStack环境检查 2.Jenkins使用基于SaltStack的CD流水线下载Nexus制品 二、问题 1.salt未找到命令 2.salt简单测试报错 3. wget输出日志过长 一、理论 1.salt常用命令 &#xff08;1&#xff09;salt 命令 该 命令执行s…

vue中 把vue页面导出为 html页面

vue导出文件后缀为html的页面 震惊&#xff01;我司要求我把数据融合起来&#xff0c;导出用html的方式展示&#xff0c;请看下面示例 <template><div><el-button click"gethtml">导出报告</el-button><div id"main"><…

「Azure架构风格」Azure云不同的 架构风格

架构风格是一系列具有某些共同特征的架构。例如&#xff0c;n层是一种常见的体系结构样式。最近&#xff0c;微服务体系结构开始受到青睐。架构风格不需要使用特定的技术&#xff0c;但是有些技术非常适合特定的架构。例如&#xff0c;容器自然适合于微服务。 我们已经确定了一…

回溯算法第三篇(批处理作业调度、N皇后【基于排列树实现】、符号三角形问题)

目录 1. 批处理作业调度 2. N皇后【基于排列树实现】 3. 符号三角形问题 1. 批处理作业调度 题目描述&#xff1a;给定n个作业的集合 。每个作业 都有两项任务分别在两台机器上完成。每个作业必须先由机器1处理&#xff0c;再由机器2处理。作业 需要机器j的处理时间为 。对…