上一篇,我们讲到,各种缓存的处理都存在一些弊端。这一篇我们讲一下,面对这些弊端的优化方式。
缓存穿透
指没有命中缓存,直接请求到数据库,会导致数据库压力过大。例如发起id='-1'的请求,而不存在这个数据,直接请求到数据库了
解决方案:
1.接口层增加检验,直接拦截id<0的请求
2.在缓存和数据库都没有找到,我们也可以设置一个key-value的缓存,例如key-null,防止重复用一个id进行暴力攻击。
缓存击穿
指缓存中没有数据,但是数据库中有(一般是缓存到期)。这时如果用记特别多的话,就容易引起数据库压力。
解决方案:
1.设置热点数据永远不过期
2.加互斥锁
$data = getData(key);
if(!$data){
if(getLock()){
//从数据库里读取数据
$data = getDataFromMysql(key);
//设置缓存
set key value;
//释放锁
releLock()
}else{
//没拿到锁暂停一会儿
sleep(100);
$data = getData(key);
}
}
缓存雪崩
指的是大批量的缓存过期,引起数据库压力过大,甚至过期。于缓存击穿不同的是,缓存击穿是同一条数据,缓存雪崩是大量缓存失效
解决方案:
1.缓存数据的过期时间设置随机,防止同一时间大量数据过期
2.如果缓存数据库是分布式部署,将热点数据均匀分布在不同缓存数据库中
3.设置热点数据永远不过期。
4.加互斥锁