架构方案
- 整体架构分层
- 应用层:通过 API 调用缓存系统,获取或存储数据。
- 缓存管理层:负责处理缓存的读写操作,根据业务规则决定缓存过期策略。
- 持久化层:将缓存数据持久化到存储介质,如文件系统或数据库。
- 基于 Java Map 接口
- 使用
ConcurrentHashMap
作为内存缓存的基础数据结构,它提供了高效的并发读写性能,适合分布式缓存系统。
设计模式
- 策略模式
- 用于实现动态调整缓存的过期策略。定义一个过期策略接口
ExpirationStrategy
,不同的过期策略实现该接口,如 FixedTimeExpiration
(固定时间过期)、AccessBasedExpiration
(基于访问时间过期)等。
- 在缓存管理类中,持有一个
ExpirationStrategy
实例,通过构造函数或 setter 方法进行注入,这样可以在运行时动态切换过期策略。
- 单例模式
- 缓存系统通常设计为单例,确保在整个应用中只有一个缓存实例,避免重复创建造成资源浪费和数据不一致。可以使用双重检查锁机制实现单例模式,保证线程安全。
核心类设计
- CacheManager 类
- 属性:
private ConcurrentHashMap<String, CacheEntry> cache;
:存储缓存数据的 ConcurrentHashMap
,其中 CacheEntry
是自定义的缓存条目类。
private ExpirationStrategy expirationStrategy;
:持有过期策略实例。
- 方法:
public CacheManager(ExpirationStrategy strategy)
:构造函数,初始化过期策略。
public void put(String key, Object value)
:将数据存入缓存,同时根据过期策略设置过期时间。
public Object get(String key)
:从缓存获取数据,先检查是否过期,过期则移除并返回 null
,否则返回数据。
- CacheEntry 类
- 属性:
private Object value;
:缓存的值。
private long expirationTime;
:过期时间。
- 方法:
public CacheEntry(Object value, long expirationTime)
:构造函数,初始化值和过期时间。
public boolean isExpired()
:判断缓存条目是否过期。
- ExpirationStrategy 接口及实现类
- ExpirationStrategy 接口:
long calculateExpirationTime();
:计算过期时间的方法。
- FixedTimeExpiration 类:
- 属性:
private long fixedExpirationTime;
:固定的过期时间。
- 方法:
public long calculateExpirationTime()
:返回固定的过期时间。
- AccessBasedExpiration 类:
- 属性:
private long accessExpirationTime;
:基于访问的过期时间。
- 方法:
public long calculateExpirationTime()
:每次访问时更新过期时间并返回。
持久化实现
- 持久化接口:定义
PersistenceStrategy
接口,包含 void persist(ConcurrentHashMap<String, CacheEntry> cache)
和 ConcurrentHashMap<String, CacheEntry> restore()
方法,分别用于持久化缓存数据和恢复缓存数据。
- 文件持久化实现:实现
FilePersistenceStrategy
类,使用 Java 的对象序列化机制将 ConcurrentHashMap
写入文件进行持久化,恢复时从文件读取并反序列化。
关键方法实现逻辑
- CacheManager 的 put 方法
public void put(String key, Object value) {
long expirationTime = expirationStrategy.calculateExpirationTime();
CacheEntry entry = new CacheEntry(value, expirationTime);
cache.put(key, entry);
// 持久化操作
persistenceStrategy.persist(cache);
}
- CacheManager 的 get 方法
public Object get(String key) {
CacheEntry entry = cache.get(key);
if (entry == null) {
return null;
}
if (entry.isExpired()) {
cache.remove(key);
return null;
}
// 访问后更新过期时间(如果是基于访问的过期策略)
if (expirationStrategy instanceof AccessBasedExpiration) {
long newExpirationTime = expirationStrategy.calculateExpirationTime();
entry.setExpirationTime(newExpirationTime);
}
return entry.getValue();
}