Redis缓存击穿及解决方案
缓存击穿
缓存击穿就是由于缓存的数据设置的过期时间已经到期或者数据库中的数据发生了修改,然后为了数据的一致性删除了缓存中的旧数据,这时由于有大量的用户请求该数据,发现缓存里不存在,所以都一起去请求数据库,导致短时间内数据库压力过大,这就是缓存击穿。
解决方案:在进入数据库时进行互斥加锁,只有一个线程能进入数据库获取数据并把它设置到缓存,其他线程就等待并从缓存中获取即可
代码实现:
public static String getData(String key){
ReentrantLock reentrantLock=new ReentrantLock();
while (true){
//先从缓存中尝试获取值
String result=getFromRedis(key);
if(result==null){
try{
//如果缓存为空,尝试获取锁,进入数据库获取值
if(reentrantLock.tryLock()){
result=getFromRedis(key);
if(result==null){
result=getFromMysql(key);
setDataToCache(key,result);
}
}else{ //如果获取不到,则说明已有线程查询数据库,线程睡眠100毫秒,然后再尝试获取值
Thread.sleep(100);
continue;
}
}catch (InterruptedException e){
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
return result;
}
}