新聞中心
緩存的策略有很多,在應(yīng)用系統(tǒng)中可根據(jù)情況 選擇,通常會把一些 靜態(tài)數(shù)據(jù)后者變化頻率不高的數(shù)據(jù)放到緩存中,如配置參數(shù)、字典表等。而有些場景可能要尋找替代方案,比如,想提升全文檢索的速度,在復(fù)雜場景下建議使用搜索引擎,如Solr或 ElasticSearch。
通常在Web開發(fā)中,不同層級對應(yīng)的緩存要求和緩存策略全然不同,如下圖:
下面了解一下緩存中的兩個比較重要的基本概念:
1. 緩存命中率
即從緩存中讀取數(shù)據(jù)的次數(shù)與總讀取次數(shù)的比率。一般來說,命中率越高越好。
命中率 = 從緩存中讀取的次數(shù) /(總讀取次數(shù)【從緩存中讀取的次數(shù) + 從慢速設(shè)備上讀取的次數(shù)】)
Miss 率 = 沒有從緩存中讀取的次數(shù) /(總讀取次數(shù)[從緩存中讀取的次數(shù) + 從慢速設(shè)備上讀取的次數(shù)])
如果要做緩存,就一定要監(jiān)控這個指標(biāo),來看緩存是否工作良好。
2.過期策略
- FIFO(First In First Out):先進(jìn)先出策略。
- LRU(Least Recently Used): 最久未使用策略,即一定時間段內(nèi)使用率最少的那個數(shù)據(jù)被溢出。
- TTL(Time to Live): 存活期,即從緩存中創(chuàng)建時間點(diǎn)開始直至到期的一個時間段。
- TTI(Time To Idle): 空閑期,即一個 數(shù)據(jù)多久沒被訪問就從緩存中移除的時間。
自定義實(shí)現(xiàn)一個緩存管理器:
首先自定義一個User實(shí)體類。
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();
}
}
提供用戶查詢的服務(wù)類,此服務(wù)類使用緩存管理器來支持用戶查詢。
public class UserService {
private CacheManager cacheManager;
public UserService() {
cacheManager = new CacheManager();
}
@Cacheable(cacheNames = "users")
public User getUserById(String userId) {
// 方法內(nèi)部實(shí)現(xiàn)不考慮緩存邏輯,直接實(shí)現(xiàn)業(yè)務(wù)
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 來實(shí)現(xiàn)上面的例子:
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);
// 如果在緩存中,則直接返回緩存的結(jié)果
return result;
}
// 否則從數(shù)據(jù)庫查詢
result = getFromDB(userId);
if (result != null) {
// 將數(shù)據(jù)庫查詢的結(jié)果更新到緩存中
cacheManager.addOrUpdate(userId, result);
}
return result;
}
public void reload() {
cacheManager.clearCache();
}
private User getFromDB(String userId) {
return new User(userId);
}
}
現(xiàn)在還需要一個Spring 配置文件來支持基于注解的緩存:
上面在UserService代碼中沒有看到任何緩存邏輯代碼,只需一個注解@Cacheable(cacheNames="users"),就實(shí)現(xiàn)了基本的緩存方案,代碼變得非常優(yōu)雅、簡潔。使用Spring Cache 只需完成以下兩個步驟:
- 緩存定義: 確定需要緩存的方法和緩存策略
- 緩存配置: 配置緩存
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。
當(dāng)前名稱:阿里P7架構(gòu)師分享:15分鐘快速掌握SpringCache(使用詳解)-創(chuàng)新互聯(lián)
瀏覽地址:http://fisionsoft.com.cn/article/gspdo.html