栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

学了一段时间的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;
    }

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/826175.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号