Reids( 缓存篇 ==> 缓存穿透解决方案

缓存穿透的常见解决方案有两种:

  • 缓存空值
  • 布隆过滤器

一、缓存空值

当客户端发送的请求在Reids缓存中和数据库中都查询失败,我们设置一个空值缓存起来,这样即使用户访问了不存在的数据,也不会让请求直接穿透的数据库上。

注意:缓存空值的过期时间不宜太长,假设我们之后真的添加了新数据,也不会造成过久的数据不一致问题。

                                 d7c0d8b9069d4cdfa3753b0a9e7e5ee6.png

缓存空值方案的优点与缺点:

缺点:

  • 缓存空值需要消耗额外的内存
  • 短期内数据不一致

优点:

  • 实现简单,我们只需要在数据库查询失败后添加个空值缓存即可

 

实现思路:

1、从Redis中查询信息

2、击中缓存了直接返回即可

3、击中空值直接返回错误信息

4、缓存没击中,查询数据库

5、数据库查询失败,说明当前所查询信息不存在,缓存一个空值到Redis(同时设置较短的过期时间)

6、数据库查询成功,添加缓存并返回

核心代码如下:

d8abdf17293d4a69b96be145ca36a8d4.png

 完整实现(带注释):

    //需求,通过ID查询店铺信息,并添加到缓存。需要保证数据一致性
    @Override
    public Result queryById(Long id) {
        //定义个cacheID作为key,后续方便使用
        String cacheId = CACHE_SHOP_KEY + id;

        //1、从Redis中查询商户信息
        String shopJson = stringRedisTemplate.opsForValue().get(cacheId);

        //2、击中了,转成对象直接返回
        if(StrUtil.isNotBlank(shopJson)){
            return Result.ok(JSONUtil.toBean(shopJson,Shop.class));
        }

        //3、击中了空值,直接返回
        //这里不能直接用shopJson.equals("")做为条件,因为第一次查询没有缓存任何数据,shopJson肯定是个null,null.equals()直接报错了
        //而上面的isNotBlank方法排除后只剩下null和""的两种情况,我们只需要再排除null的情况,剩下的就是""了。
        if(shopJson != null){
            return Result.fail(SHOP_ERROR);
        }

        //4、缓存没击中,去数据库查
        Shop shop = getById(id);

        //5、数据库里也没查到,返回空对象到Redis(防止缓存穿透)
        if(shop == null){
            stringRedisTemplate.opsForValue().set(cacheId,"");
            stringRedisTemplate.expire(cacheId,CACHE_NULL_TTL,TimeUnit.MINUTES);
            return Result.fail(SHOP_ERROR);
        }

        //6、添加数据到redis缓存
        stringRedisTemplate.opsForValue().set(cacheId,JSONUtil.toJsonStr(shop));

        //7、设置过期时间,30分钟
        stringRedisTemplate.expire(cacheId,CACHE_SHOP_TTL, TimeUnit.MINUTES);

        //8、返回数据
        return Result.ok(shop);

    }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白日日白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值