Redis缓存穿透、缓存击穿、缓存雪崩区别和解决方案

1. 缓存穿透
        用户不断的向服务器发送请求查询不存在的数据(缓存中和数据库中均不存在),每次查询数据的时候服务器都会查询数据库,导致服务器压力增大。

1.1 产生原因

        redis查询不到数据库。

        出现很多非正常URL访问。

1.2 解决方案:

        对空值缓存:对查询结果为空的请求也更新缓存,并设置一个短时间的过期时间,这样下次查询就从缓存中读取结果,降低了数据库的读取压力。

        设置可访问的名单(白名单): 禁止发送大量无意义请求的IP访问。

        采用布隆过滤器: 对所有可能查询的参数以hash形式存储,当用户想要查询的时候,使用布隆过滤器发现不在集合中,就直接丢弃,不再对持久层查询。

2. 缓存击穿
        缓存中某个数据过期了,而此时有大量请求访问这个过期的数据,此时大量请求同时访问数据库,导致数据库压力瞬时增大。

2.1 产生原因:

        redis某个key过期了, 大量访问使用这个key。
2.2 解决方案:

        设置热点数据永不过期。

        使用互斥锁。

3. 缓存雪崩
        在极短的时间里,大量缓存中的数据集中过期,导致大量请求同时访问数据库,而查询数据量巨大,引起数据库压力过大甚至down机。

注:雪崩时大量数据过期,击穿时热点数据过期。

3.1 产生原因:

        在极少时间段, 查询大量key的集中过期情况
3.2 解决方案:

构建多级缓存架构。

使用锁或队列。

设置过期标志更新缓存。

将缓存失效时间分散开。

    /**
     * 解决缓存雪崩
     * @return
     */
    public User getUser2(String userId) {
        //从缓存中获取user信息
        User user = (User) redisTemplate.opsForValue().get(userId);

        if(user == null) {
            //如果缓存数据为空,从数据库中获取user信息
            user = lUserMapper.getUserByUserId(userId);

            if(user == null) {
                redisTemplate.opsForValue().set(userId,null,3, TimeUnit.MINUTES);
            }else {
                //设置随机过期时间,将数据写入缓存,防止缓存雪崩
                long mins = random.nextInt(60) + 60;
                redisTemplate.opsForValue().set(userId, user, mins, TimeUnit.MINUTES);
            }
        }
        return user;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值