您好,登錄后才能下訂單哦!
緩存的策略有很多,在應用系統中可根據情況 選擇,通常會把一些 靜態數據后者變化頻率不高的數據放到緩存中,如配置參數、字典表等。而有些場景可能要尋找替代方案,比如,想提升全文檢索的速度,在復雜場景下建議使用搜索引擎,如Solr或 ElasticSearch。
通常在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<T> {
private Map<String, T> cache = new ConcurrentHashMap<String, T>();
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<User> cacheManager;
public UserService() {
cacheManager = new CacheManager<User>();
}
@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<User> cacheManager;
public UserServiceUseSpringCache() {
cacheManager = new CacheManager<User>();
}
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 配置文件來支持基于注解的緩存:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 啟動基于注解的緩存驅動 這個配置項默認使用了一個定義為cacheManager的緩存管理器。 -->
<cache:annotation-driven />
<bean id="accountServiceBean" class="cacheOfAnno.AccountService"/>
<!-- generic cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" />
<bean
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="users" />
</set>
</property>
</bean>
</beans>
上面在UserService代碼中沒有看到任何緩存邏輯代碼,只需一個注解@Cacheable(cacheNames="users"),就實現了基本的緩存方案,代碼變得非常優雅、簡潔。使用Spring Cache 只需完成以下兩個步驟:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。