Redis缓存预热、雪崩、击穿、穿透以及性能监控
程序员文章站
2022-06-19 11:33:15
...
缓存预热
就是在热点数据在使用前,就已经被加载到 Redis 中了。避免出现用户在使用热点数据时,先去数据库查,然后再保存到 Redis 中的过程。
缓存雪崩
问题出现原因:在较短时间内,大量的缓存数据集中过期了。如在代码中,对大批量的热点数据设置了30min过期,30min过后,大批量的热点数据都将被 Redis 删除掉,于是便出现了大量的请求需要去操作数据库。
解决方案:
- 对热点数据的过期时间,再添加一个随机值,避免出现极短的时间内大量缓存数据被删除的情况。
- 限流降级,限制部分请求访问
缓存击穿
缓存击穿是指某一个热点数据过期了,但同时又有大批量请求来访问该数据,导致大量的请求到了 DB 上。它与缓存雪崩相似,缓存雪崩指的是多个 key ,缓存击穿指的是某一个 key。
解决方案:
- 适当的延长该类型 key 过期时间
- 使用分布式锁,让一个请求去加载数据到缓存中,避免大量请求到达 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;
}
上一篇: linux stat
下一篇: python常用工具组件