缓存穿透
大量用户查询数据库没有的数据,导致数据库长时间处于被大量访问的状态
- 将这些请求的数据存储到redis里,过期时间设置短点,避免大量的空对象占据过多的空间
- 在微服务网关或拦截器中设置逻辑监控,限制IP对同一数据的访问量,防止通过缓存穿透进行的恶意攻击
- 使用布隆过滤器(Bloom Filter)进行拦截
布隆过滤器资料布隆(Bloom Filter)过滤器——全面讲解,建议收藏_李子捌的博客-CSDN博客
缓存击穿
指要查询的数据在缓存中没有,要到数据库里找,但同一时间有大量用户查询这个数据,导致数据库压力飙升
处理方案:
-
缓存预热:
- 将长期不会发生变动且经常被查询的数据,设置永不过期。
- 将会处于热点的数据,延长过期时间至热度下降的时间,如新发布的活动。
-
限流降级:缓存击穿就是同一时间有大量的用户进行访问同一数据,只要在访问时缓存不存在就进行上锁,限制对数据库的访问量,当从数据库获取数据后,存储到缓存里再释放锁。
public String getData(String key) throws InterruptedException {
// 首先从缓存读取数据
String val = getDataFromRedis(key);
// 如果缓存不存在则去数据库获取
if (val == null) {
// 获取锁
if (lock.tryLock()) {
// 从数据库获取数据
val = getDataFromDB(key);
if (val != null) {
setCache(key, val);
}
// 释放锁
lock.unlock();
} else {
// 其他线程获取锁失败,睡眠100毫秒后尝试重新获取
Thread.sleep(100);
val = getData(key);
}
}
return val;
}
缓存雪崩
大量缓存同时失效
- 尽量避免缓存过期时间设置在同一时间
- 多增设几台redis,避免一台redis挂掉导致出现的缓存雪崩
- 与缓存击穿的缓存预热和限流降级一样,减少缓存失效时对数据的压力