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

文章讨论了缓存穿透问题及其对数据库的影响,提出两种解决方案:一是缓存空对象并设置TTL来减轻数据库压力,二是利用布隆过滤器减少误判。布隆过滤器是一种高效的数据结构,能有效防止非存在的数据查询对数据库造成冲击。同时,文章提供了一个具体的Java代码示例,展示如何在查询商铺时处理缓存穿透,并强调应结合主动策略如数据校验和权限控制来增强系统稳定性。
摘要由CSDN通过智能技术生成

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. 做好热点参数的限流
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值