缓存穿透
缓存和数据库均不存在(申请打到缓存,未查问到,接着查询数据库,也没有查到)时,大量并发会对数据库造成极大压力。
解决方案
- 设置一个key-null的缓存,并将生效工夫能够设置短一点(比方30s), 这样雷同申请就不会间接打到数据库。
- 应用BloomFilter,相当于在查问缓存之前先在汇合中查问key是否存在,如果不存在就间接返回
-
- *
缓存雪崩
同一时刻大量缓存生效,导致申请全部打到数据库。
解决方案
- 缓存数据的过期工夫设置随机,避免同一时间大量数据过期景象产生
- 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中
- 设置热点数据永不过期
-
- *
缓存击穿
缓存雪崩的一种,雪崩是多个key生效,击穿是指某个key生效,同一时刻,大量的雷同申请会间接打到数据库。
解决方案
- 设置热点数据永不过期。
- 采纳互斥锁
static Lock reenLock = new ReentrantLock();
public List<String> getData() throws InterruptedException {
List<String> result = new ArrayList<String>();
// 从缓存读取数据
result = getDataFromCache();
if (result.isEmpty()) {
if (reenLock.tryLock()) {
try {
System.out.println("我拿到锁了,从DB获取数据库后写入缓存");
// 从数据库查问数据
result = getDataFromDB();
// 将查问到的数据写入缓存
setDataToCache(result);
} finally {
reenLock.unlock();// 开释锁
}
} else {
result = getDataFromCache();// 先查一下缓存
if (result.isEmpty()) {
System.out.println("我没拿到锁,缓存也没数据,先小憩一下");
Thread.sleep(100);// 小憩一会儿
return getData();// 重试
}
}
}
return result;
}
发表回复