什么是缓存穿透?怎么解决?

什么是缓存穿透?怎么解决?,第1张

学了一段时间的redis了,但是还是感觉有点糊,一边学习一边回顾总结叭                     

 

1.缓存穿透 1.1什么是缓存穿透?

答:是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库

2.2解决方案通常有两种

①缓存空对象

优点:实现简单,维护方便

缺点:额外的内存消耗,可能造成短期的不一致

②布隆过滤

优点:内存占用较少,没有多余key

缺点:实现复杂,存在误判可能

3.实现①缓存空对象结局方案:

客户端请求到redis未命中,请求数据库也未命中,服务端就向redis缓存null空值,并设置有效期,使下次请求的不存在数据直接在redis缓存层就被拦截,不会再请求到数据库,减小数据库压力。

如果数据库在有效期内更新之前未存在的数据,会造成短期数据不一致。

4.实现代码
 //缓存穿透解决方案
    public Shop queryWithPassThrough(Long id){
        //1.从redis查询商铺缓存
        String shopJson = stringRedisTemplate.opsForValue().get(RedisConstants.CACHE_SHOP_KEY + id);
        //2.判断是否为空 isNotBlank判断某字符串是否不为空且长度不为0且不由空白符(whitespace)构成,
        if(StrUtil.isNotBlank(shopJson)){
            //3.存在直接返回
            Shop shop = JSONUtil.toBean(shopJson, Shop.class);
            return JSONUtil.toBean(shopJson,shop.getClass());
        }
        // 如果shopJson 不是null 且为空(上面判断) 证明这就是我们防止缓存穿透设置的空值
        if (shopJson!=null){
            //返回一个null信息
            return null;
        }
        
//        4,不存在根据id查询数据库
        Shop shop = getById(id);
//        5.不存在 返回错误
        if (shop==null){
            //将空值写入redis(防止缓存击穿问题)
            //redis set命令就是key value time timetype  字段是我项目需要,不必在意他的含义
            stringRedisTemplate.opsForValue().set(RedisConstants.CACHE_SHOP_KEY+ id,"",2L,TimeUnit.MINUTES);
            return  null;
        }
//        6.存在,写入redis 并设置缓存时间有效期为30分钟
        stringRedisTemplate.opsForValue().set(RedisConstants.CACHE_SHOP_KEY+ id,JSONUtil.toJsonStr(shop),RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);
//        7.返回
        return shop;
    }

最后写一段,有很多问题,根本没有完美的方案,只有最适合的方案,总是要接受一些不完美。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/720265.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存