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

这篇具有很好参考价值的文章主要介绍了【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


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

🍔什么是缓存穿透

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

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

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

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

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

🎄解决办法

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

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

⭐缓存空值处理

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

🎈优点

实现简单,维护方便

🎈缺点

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

🎍代码实现

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

@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);
}

⭐布隆过滤器

【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用),SpringBoot,spring boot,缓存,spring,布隆过滤器
布隆过滤器是一种空间效率高、适合大规模数据的概率型数据结构,用于判断一个元素是否可能存在于一个集合中。布隆过滤器由一个位数组和多个哈希函数组成。其核心思想是通过多个哈希函数对输入元素进行映射,将元素映射到位数组的多个位置上,从而实现元素的快速查找。

假设布隆过滤器使用一个长度为 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>

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

编写核心代码

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

@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);
    }

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

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

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

【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用),SpringBoot,spring boot,缓存,spring,布隆过滤器文章来源地址https://www.toymoban.com/news/detail-762698.html

到了这里,关于【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于Guava布隆过滤器的海量字符串高效去重实践

    在Java环境中处理海量字符串去重的问题时,布隆过滤器(BloomFilter)是一种非常高效的数据结构,尽管它有一定的误报率。布隆过滤器适用于那些可以接受一定误报率,并且希望节省空间和时间成本的场景。 使用Google Guava库来实现基于布隆过滤器的海量字符串去重是一个很好

    2024年01月24日
    浏览(43)
  • 算法~布隆过滤器

    布隆过滤器(Bloom Filter)是一种高效的概率数据结构,用于判断一个元素是否存在于集合中。它基于位数组和多个哈希函数,并具有以下特点: Bloom Filter 是一个基于概率的数据结构:它只能告诉我们一个 元素绝对不在集合内 或 可能在集合内 快速查询:布隆过滤器具有快速

    2024年02月05日
    浏览(47)
  • 布隆过滤器的原理

    布隆过滤器是一种用于检索一个元素是否在一个集合中的数据结构,具有高效的查询性能和较小的内存占用。 布隆过滤器的底层实现主要涉及以下几个步骤: 初始化数组: 首先,初始化一个比较大的数组,数组中的元素用二进制表示,初始值都为0。 Hash计算: 当一个新的元

    2024年01月18日
    浏览(40)
  • 布隆过滤器及其应用

    布隆过滤器是一种数据结构,具有快速插入和查找的特性,能确定某个字符串一定存在或者可能存在。布隆过滤器有着高效的空间利用率,它不存储具体数据,只存储数据的关键标识,所以占用的空间较小。它的查询结果可能会存在一定误差,但是误差总体可控,同时不支持

    2024年02月03日
    浏览(44)
  • 位图以及布隆过滤器

    本文主要讲解哈希思想的实际应用,位图和布隆过滤器。 讲解位图之前我们先来解答这样一道腾讯的面试题 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】 很多人立马就想到了用哈希表或者红黑树,因为足够

    2024年02月08日
    浏览(53)
  • 布隆过滤器详解

    本文全部代码地址 布隆过滤器是一种高效的数据结构,用于判断一个元素是否存在于一个集合中.它的主要优点是速度快,空间占用少,因此在需要快速判断某个元素是否在集合中的场合得到广泛引用. 布隆过滤器就是 一个大型的位数组和几个不一样的无偏hash函数. 所谓无偏就是

    2023年04月22日
    浏览(54)
  • Redis----布隆过滤器

    目录 背景 解决方案 什么是布隆过滤器 布隆过滤器的原理 一些其他运用 比如我们在观看新闻或者刷微博的时候,会不停地给我们推荐新的内容,我们发现几乎没有重复的,说明后台已经进行了去重处理,基于如何去重,Redis给出了高效的方案---布隆过滤器 1.记录已经浏览过

    2024年02月09日
    浏览(38)
  • 哈希的应用——布隆过滤器

    上一篇文章,我们学习了位图,位图在某些场景下是非常适用的,非常快捷方便。 但是,在文章的最后,我们也提出了位图的一些缺陷——比如位图只能映射整型数据,其它类型的数据则不行。 因为位图里面的元素去映射的其实就是下标嘛,而下标的话都是整型啊。 那有没

    2024年02月09日
    浏览(42)
  • Java实现布隆过滤器

    背景: 为预防大量黑客故意发起非法的时间查询请求,造成缓存击穿,建议采用布隆过滤器的方法解决。布隆过滤器通过一个很长的二进制向量和一系列随机映射函数(哈希函数)来记录与识别某个数据是否在一个集合中。如果数据不在集合中,能被识别出来,不需要到数据

    2024年02月01日
    浏览(48)
  • 布隆过滤器:原理与应用

    本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 目录 布隆过滤器简介 fpp 布隆过滤器原理 布隆过滤器的特点 布隆过滤器使用 布隆过滤器中的数据可不可以删除 布隆过滤器应该设计为多大 布隆过滤器应

    2024年02月08日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包