详解redis的缓存穿透解决策略(含代码样例)

目录

缓存穿透

解决方案

 实际项目中应用(采用缓存空值的方式)

缓存穿透产生的原因是什么?

缓存穿透的解决方案有哪些?


缓存穿透

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

解决方案

常见的解决方案有两种:

缓存空对象
优点:实现简单,维护方便
缺点:
额外的内存消耗
可能造成短期的不一致
布隆过滤
优点:内存占用较少,没有多余 key
缺点:
实现复杂
存在误判可能

缓存空值:

详解redis的缓存穿透解决策略(含代码样例)_第1张图片

布隆过滤器:

详解redis的缓存穿透解决策略(含代码样例)_第2张图片

 实际项目中应用(采用缓存空值的方式)

项目之前的逻辑:

详解redis的缓存穿透解决策略(含代码样例)_第3张图片

 示例代码:

 @Override
    public Result queryById(Long id) {
        String key = CACHE_SHOP_KEY + id;
        //1.从redis中查询店铺缓存
        String jsonShop = stringRedisTemplate.opsForValue().get(key);
        //2.判断是否存在
        if (StrUtil.isNotBlank(jsonShop)) {
            //3.存在,直接返回
            Shop shop = JSONUtil.toBean(jsonShop, Shop.class);
            return Result.ok(shop);
        }
       
        //4.不存在,根据id查询数据库
        Shop shop = getById(id);
        //5. 不存在 返回错误
        if(shop == null){
          
            return Result.fail("店铺不存在!");
        }
        // 6. 存在 写入 redis
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
        //7.返回
        return Result.ok(shop);
    }

采用缓存空值解决缓存穿透

详解redis的缓存穿透解决策略(含代码样例)_第4张图片

 示例代码:

  @Override
    public Result queryById(Long id) {
        String key = CACHE_SHOP_KEY + id;
        //1.从redis中查询店铺缓存
        String jsonShop = stringRedisTemplate.opsForValue().get(key);
        //2.判断是否存在
        if (StrUtil.isNotBlank(jsonShop)) {
            //3.存在,直接返回
            Shop shop = JSONUtil.toBean(jsonShop, Shop.class);
            return Result.ok(shop);
        }
        if("".equals(jsonShop)){
            return Result.fail("店铺信息不存在!");
        }
        //4.不存在,根据id查询数据库
        Shop shop = getById(id);
        //5. 不存在 返回错误
        if(shop == null){
            // 将空值放入redis
            stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL,TimeUnit.MINUTES);
            return Result.fail("店铺不存在!");
        }
        // 6. 存在 写入 redis
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
        //7.返回
        return Result.ok(shop);
    }

缓存穿透产生的原因是什么?

用户请求的数据在缓存中和数据库中都不存在,不断发起这样的请求,给数据库带来巨大压力

缓存穿透的解决方案有哪些?

缓存 null
布隆过滤
增强 id 的复杂度,避免被猜测 id 规律
做好数据的基础格式校验
加强用户权限校验
做好热点参数的限流

你可能感兴趣的:(redis,缓存,redis)