-
三大经典问题
1. 缓存穿透
一旦缓存没有,直接到数据库去查找,如果缓存不大的情况下,无伤大雅,但是当高并发场景下,大量的请求直接穿透缓存直接查询数据库
- 原因分析
- 在数据库中没有相对应的查询结果
- 查询结果为空时不对查询进行缓存(这里可以缓存个空值)
- 如何解决
- 对非法请求进行限制
- 对结果为空的查询给出默认值
2. 缓存击穿
当一个热点数据的失效时间到了的时候,然后突然有大量的请求涌入,这些请求最终都发送到数据库导致数据库崩溃
- 原因分析
- 热点数据突然失效
- 如何解决
- 双重检测锁
@Override
public Double findTurnover() {
// 获取Redis指定key的操作对象
BoundValueOperations<Object, Object> ops = redisTemplate.boundValueOps("turnover");
// 从缓存中读取指定key的value
Object turnover = ops.get();
if (turnover == null) {
synchronized (this){
System.out.println("redis里面不存在");
turnover = ops.get();
if(turnover==null){
// 获取当前日期,并格式化
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
turnover = dao.selectTurnover(sdf.format(date));
// 将查询结果写入到缓存
ops.set(turnover, 10, TimeUnit.SECONDS);
}
}
}
return (Double) turnover;
}
使用双重检测锁机制预防缓存击穿
若缓存中没有该数据,则先从DB中查询,然后再写入到缓存
上一把锁 其实就是把数据库的压力 直接锁到 代码层
3. 缓存雪崩
对于缓存中的数据 很多都是存在过期时间的,如果大量的缓存的国企时间在同意很短的时间段内几乎同时到大,那么在高并发访问场景下可能会引发DBMS的高并发查询 这样可能会导致DBMS的崩溃,这种情况下称之为缓存雪崩。
- 原因分析
- 大量热点数据突然失效
- 如何解决
- 无法解决只能进行预防
- 也可以延长热点数据的过期时间
- 要不然可以把热点数据放在分布式系统当中,可以有效的进行缓冲