缓存
一、基本概念
- 缓存是将数据存储在读写性能更好的介质,让访问速度更快。缓存本质是真实数据的拷贝。
二、应用场景
数据特点 | 是否适合缓存 | 效果 |
---|
访问频率高的数据 | 适合 | 效果好 |
访问频率低的数据 | 不适合 | 效果不好 |
读写比例高的数据 | 适合 | 效果好 |
读写比例低的数据 | 不适合 | 效果不好 |
数据一致性要求高 | 适合 | 效果好 |
数据一致性要求低 | 不适合 | 效果不好 |
三、缓存指标和缓存过期
3.1 命中率
- 应用请求数据时,先从缓存查询,如果查询缓存成功则命中缓存直接返回。
如果查询缓存失败,则查询数据库,并将数据库的记录同步到缓存。前者称为缓存命中,后者则没有命中,显然我们期望命中以提高性能。命中的比例称为命中率。
3.2 缓存过期
- 前面提过缓存本质是是数据库记录的拷贝,那么数据库中的记录被更新后缓存没有更新的话,后续请求就可能访问到缓存中的脏数据。因此缓存需要有一个过期时间。
3.2.1 绝对过期
- 比如数据保存到缓存中之后,设置其过期时间是5S,这个是绝对的过期时间,过程中不管缓存有没有本访问到,都会在5S后清除。
3.2.2 滑动过期
- 滑动过期是当每一次访问缓存的时候,都会往后更新过期时间。比如在1S的时刻数据放入缓存,过期时间是5S,那么数据应该在第6S的时刻过期,如果在第3秒访问了缓存,那么会在第3秒的时刻再次设置过期时间是5S,那么数据会在低8秒过期。换言之只有在连续的5S数据没有被访问到,数据才会清除。
四、缓存访问的模板流程
result = queryFromCache(id); //1.缓存查询
if(result != null){
return result; //2.缓存有就返回
}
//3.缓存没有就查数据库,需要加锁避免并发请求数据库
lock(id);
try{
//4.获取锁之后,有可能另一个读请求已经将数据加载到缓存了,因此尝试一次缓存中获取
result = queryFromCache(id);
if(result != null){
return result; //5.获取成功返回
}
result = queryFromDb(id);//6.缓存中没有即请求数据库
if(result != null){
setCache(result);//7.将结果放入缓存
}
return result;
}finally{
unLock(id);//8.finally保证锁会释放
}