-
分佈式緩存需要遠程調用,多了一次網絡開銷。
-
同樣情況下,分佈式緩存要慢於本地緩存。
-
本地緩存不能跨區域共享。
-
Cache Aside:適用於輕量級應用
-
Read/Write Through:適合需要頻繁使用緩存的應用
-
Write Back:適合數據一致性不高的場景
public class LocalCache<K,V> implements Cacheable<K,V>{
// 緩存數據的集合
private Map<K, Data> map = new ConcurrentHashMap<>();
// 每60s請理過期數據,延遲1s執行
public LocalCache(){
Timer t = new Timer();
t.schedule(new ExpiringChecker(), 1000, 60 * 1000);
}
@Override
public V get(K key) {
Data data = map.get(key);
if (isExpired(data)) {
delete(key);
return null;
}
return data.getVal();
}
private boolean isExpired(Data data) {
if (data == null) {
return true;
}
return data.getExpire() > 0 && Instant.now().toEpochMilli() > data.getExpire();
}
/**
* 添加數據
* @param key
* @param val
* @param expire 過期時間,單位s
*/
@Override
public void set(K key, V val, long expire) {
map.put(key, new Data(val, expire));
}
@Override
public void delete(K key) {
map.remove(key);
}
@Override
public boolean exist(K key) {
return map.containsKey(key);
}
// 數據包裝類,保存val的時間戳
private class Data{
V val;
long expire;
Data(V val, long expire) {
this.val = val;
this.expire = expire > 0 ? Instant.now().toEpochMilli() + expire * 1000 : expire;
}
public V getVal() {
return val;
}
public void setVal(V val) {
this.val = val;
}
public long getExpire() {
return expire;
}
public void setExpire(long expire) {
this.expire = expire;
}
}
/**
* 過期數據檢測器
*/
private class ExpiringChecker extends TimerTask{
@Override
public void run() {
map.forEach((k, v) -> {
if (isExpired(v)) {
delete(k);
}
});
}
}
}