缓存穿透
Ⅰ、什么是缓存穿透?
当一个访问的目标数据在数据库中没有,在缓存中也没有。此时有人故意的去访问这个数据,并且是巨量的访问,由于redis缓存中没有该数
据,所有的访问就全部到了数据库,数据库最终不堪重负,就挂掉了。
Ⅱ、解决方案:
如果请求的数据在redis和数据库中都没有,那就在放置一个空对象值在redis,保证该请求的有返回值。同时给该值设置一个存活时间,让它存活一段时间就清楚,避免占内存空间。下次如果还有该请求,就再次放一个空对象值。
NullObject.java:
public class NullObject {
private int id=0;
}
业务类:DeptService2.java
@Service
public class DeptService2 {
@Resource
private DeptDao deptDao;
@Autowired
private RedisTemplate redisTemplate;
public Dept findById(Integer deptId){
//1.从缓存中查询该数据
Object o = redisTemplate.opsForValue().get("findById::" + deptId);
if(o!=null){//表示从缓存中获取该数据
if(o instanceof NullObject){
return null;
}
return (Dept) o;
}
Dept dept = deptDao.selectById(deptId);
if(dept==null){//数据库中没有该记录
redisTemplate.opsForValue().set("findById::"+deptId,new NullObject(),5, TimeUnit.MINUTES);
}else {
redisTemplate.opsForValue().set("findById::" + deptId, dept);//把查询的结果放入缓存
}
return dept;
}
}
二、缓存雪崩
1、什么是缓存雪崩?
在某一时刻,缓存中没有数据,但是同时有大量的访问,这样访问又全部到了数据库,造成数据压力过大,挂掉了。
2、造成缓存雪崩的部分原因以及解决方案
(1)、同一时刻redis中大量数据到期。------使用散列时间
(2)、项目刚上线,redis中没有数据。------对项目进行预访问,给redis中增加数据
(3)、使用MQ(队列)控制访问流量