前言
之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结
源码:weloe/Java-Distributed-Cache (github.com)
本篇代码:
Java-Distributed-Cache/src/main/java/com/weloe/cache/cachemanager at master · weloe/Java-Distributed-Cache (github.com)
Java-Distributed-Cache/src/test/java/com/weloe/cache/cachemanager at master · weloe/Java-Distributed-Cache (github.com)
上篇:
https://www.cnblogs.com/weloe/p/17050512.html
思路
既然是分布式缓存,那么就一定会有缓存管理方面的问题,既然是要储存的数据,那么就不能让它无限制的存储,就需要设置临界值,这个也是需要缓存淘汰的原因。
而为了对缓存方便管理,比如,我们需要缓存的有多个功能,我们为了方便区分,可能就需要在key前加上功能前缀,这样不仅变得麻烦,同时由于key变大,也会增加内存的压力。
所以我们就需要把缓存分组进行管理,并提供一些方便的对外接口
实现
CacheObj
Java-Distributed-Cache/CacheObj.java at master · weloe/Java-Distributed-Cache (github.com)
在前篇缓存淘汰中,我们确定了我们真正存储数据的是一个k,v结构,因此,我们需要抽象出这里的k,v,k选择String,而v则抽象出一个CacheObj。
需要注意的是,这里的endTime是该缓存到期的时间,一般而言,我们都有为目标缓存设定缓存时间的需求,这也是缓存淘汰策略中的一种。实际存储为byte[]则是为了通用性。
public class CacheObj {
private LocalDateTime endTime;
private Class clazz;
private int byteSize;
// 存储的实际数据
private byte[] data;
public CacheObj() {
}
public CacheObj(LocalDateTime endTime,Class clazz ,int byteSize, byte[] data) {
this.endTime = endTime;
this.clazz = clazz;
this.byteSize = byteSize;
this.data = data;
}
public int getByteSize() {
return byteSize;
}
public byte[] getData() {
return data;
}
public void setEndTime(LocalDateTime endTime) {
this.endTime = endTime;
}
public LocalDateTime getEndTime() {
return endTime;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
}
Cache
Java-Distributed-Cache/Cache.java at master · weloe/Java-Distributed-Cache (github.com)
有组管理,也就需要单一的缓存管理
public class Cache {
// 最大字节
private int maxByteSize;
// 目前使用字节
private int normalByteSize;
// 缓存策略
private CacheStrategy<String, CacheObj> cacheStrategy;
Lock readLock;
Lock writeLock;
public Cache(int maxByteSize, CacheStrategy<String, CacheObj> cacheStrategy) {
this.maxByteSize = maxByteSize;
this.normalByteSize = 0;
this.cacheStrategy = cacheStrategy;
readLock = new ReentrantReadWriteLock().readLock();
writeLock = new ReentrantReadWriteLock().writeLock();
}
public CacheObj add(String key, CacheObj cacheObj) {
writeLock.lock();
normalByteSize += cacheObj.getByteSize();
// 缓存上限
while (normalByteSize > maxByteSize) {
// 淘汰缓存
CacheObj outCache = cacheStrategy.outCache();
normalByteSize -= outCache.getByteSize();
}
// 加入缓存
CacheObj v = cacheStrategy.put(key, cacheObj);
writeLock.unlock();
return v;
}
public CacheObj get(String key) {
readLock.lock();
CacheObj v = cacheStrategy.get(key);
// 判断是否过期
if (v != null && v.getEndTime() != null && LocalDateTime.now().isAfter(v.getEndTime())) {
CacheObj obj = cacheStrategy.outCache(key);
return null;
}
readLock.unlock();
return v;
}
public CacheObj remove(String key){
return cacheStrategy.outCache(key);
}
public void clear(){
cacheStrategy.clear();
}
public void setMaxByteSize(int maxByteSize) {
this.maxByteSize = maxByteSize;
}
public int getMaxByteSize() {
return maxByteSize;
}
public int getNormalByteSize() {
return normalByteSize;
}
}
Group
Java-Distributed-Cache/Group.java at master · weloe/Java-Distributed-Cache (github.com)
既然需要组管理,那么就需要抽象出