欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis缓存预热、雪崩、击穿、穿透以及性能监控

程序员文章站 2022-06-19 11:33:15
...

缓存预热

  就是在热点数据在使用前,就已经被加载到 Redis 中了。避免出现用户在使用热点数据时,先去数据库查,然后再保存到 Redis 中的过程。

缓存雪崩

  问题出现原因:在较短时间内,大量的缓存数据集中过期了。如在代码中,对大批量的热点数据设置了30min过期,30min过后,大批量的热点数据都将被 Redis 删除掉,于是便出现了大量的请求需要去操作数据库。

解决方案:

  1. 对热点数据的过期时间,再添加一个随机值,避免出现极短的时间内大量缓存数据被删除的情况。
  2. 限流降级,限制部分请求访问

缓存击穿

缓存击穿是指某一个热点数据过期了,但同时又有大批量请求来访问该数据,导致大量的请求到了 DB 上。它与缓存雪崩相似,缓存雪崩指的是多个 key ,缓存击穿指的是某一个 key。

解决方案:

  1. 适当的延长该类型 key 过期时间
  2. 使用分布式锁,让一个请求去加载数据到缓存中,避免大量请求到达 DB。实现代码可参考如下:
    private String getKey(String key){
        String value = stringRedisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(value)){//缓存过期了
            RLock lockKey = redisson.getLock("lockKey");
            try {
                //4秒内等待尝试获取锁;如果获取成功,加3s的锁(该类型的锁每隔3s/3s,检测锁是否存在;如果锁存在重新设置超时时间为3s,如果不存在,则不做处理)。
                boolean lockSuccess = lockKey.tryLock(4, 3, TimeUnit.SECONDS);
                if(lockSuccess){//加锁成功,当前线程去读取 DB 并设置缓存
                    value = db.get(key);
                    stringRedisTemplate.opsForValue().set(key, value, 10,TimeUnit.SECONDS);
                }else {//加锁失败,证明已有其他线程执行了上面两行代码
                    value=stringRedisTemplate.opsForValue().get(key);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lockKey.unlock();
            }
        }
        return value;
    }
相关标签: Redis