缓存的策略有很多,在应用系统中可根据情况 选择,通常会把一些 静态数据后者变化频率不高的数据放到缓存中,如配置参数、字典表等。而有些场景可能要寻找替代方案,比如,想提升全文检索的速度,在复杂场景下建议使用搜索引擎,如Solr或 ElasticSearch。
创新互联专注于企业全网营销推广、网站重做改版、蓝田网站定制设计、自适应品牌网站建设、H5开发、成都做商城网站、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为蓝田等各大城市提供网站开发制作服务。
通常在Web开发中,不同层级对应的缓存要求和缓存策略全然不同,如下图:
下面了解一下缓存中的两个比较重要的基本概念:
1. 缓存命中率
即从缓存中读取数据的次数与总读取次数的比率。一般来说,命中率越高越好。
命中率 = 从缓存中读取的次数 /(总读取次数【从缓存中读取的次数 + 从慢速设备上读取的次数】)
Miss 率 = 没有从缓存中读取的次数 /(总读取次数[从缓存中读取的次数 + 从慢速设备上读取的次数])
如果要做缓存,就一定要监控这个指标,来看缓存是否工作良好。
2.过期策略
首先自定义一个User实体类。
public class User implements Serializable {
private String userId;
private String userName;
private int age;
public User(String userId) {
this.userId = userId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
接下来定义一个缓存管理器:
public class CacheManager {
private Map cache = new ConcurrentHashMap();
public T getValue(Object key) {
return cache.get(key);
}
public void addOrUpdate(String key, T value) {
cache.put(key, value);
}
public void delCache(String key) {
if (cache.containsKey(key)) {
cache.remove(key);
}
}
public void clearCache() {
cache.clear();
}
}
提供用户查询的服务类,此服务类使用缓存管理器来支持用户查询。
public class UserService {
private CacheManager cacheManager;
public UserService() {
cacheManager = new CacheManager();
}
@Cacheable(cacheNames = "users")
public User getUserById(String userId) {
// 方法内部实现不考虑缓存逻辑,直接实现业务
System.out.println("read quert user. " + userId);
return getFromDB(userId);
}
public void reload() {
cacheManager.clearCache();
}
private User getFromDB(String userId) {
return new User(userId);
}
}
使用SpringCache 来实现上面的例子:
public class UserServiceUseSpringCache {
private CacheManager cacheManager;
public UserServiceUseSpringCache() {
cacheManager = new CacheManager();
}
public User getUserById(String userId) {
User result = cacheManager.getValue(userId);
if (result != null) {
System.out.println("get from cache..." + userId);
// 如果在缓存中,则直接返回缓存的结果
return result;
}
// 否则从数据库查询
result = getFromDB(userId);
if (result != null) {
// 将数据库查询的结果更新到缓存中
cacheManager.addOrUpdate(userId, result);
}
return result;
}
public void reload() {
cacheManager.clearCache();
}
private User getFromDB(String userId) {
return new User(userId);
}
}
现在还需要一个Spring 配置文件来支持基于注解的缓存:
上面在UserService代码中没有看到任何缓存逻辑代码,只需一个注解@Cacheable(cacheNames="users"),就实现了基本的缓存方案,代码变得非常优雅、简洁。使用Spring Cache 只需完成以下两个步骤: