以下是一个基于Spring Boot的多级缓存架构实现示例
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
dependency>
<dependency>
<groupId>com.github.ben-manes.caffeinegroupId>
<artifactId>caffeineartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
@Configuration
@EnableCaching
public class MultiLevelCacheConfig {
// 一级缓存(本地缓存)
@Bean
public CacheManager caffeineCacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager();
manager.setCaffeine(Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(30, TimeUnit.SECONDS)); // 本地缓存比Redis缓存更短
return manager;
}
// 二级缓存(Redis缓存)
@Bean
public CacheManager redisCacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(5))
.serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.transactionAware()
.build();
}
// 组合缓存管理器
@Bean
@Primary
public CacheManager multiLevelCacheManager(
@Qualifier("caffeineCacheManager") CacheManager level1,
@Qualifier("redisCacheManager") CacheManager level2) {
return new MultiLevelCacheManager(level1, level2);
}
}
public class MultiLevelCacheManager implements CacheManager {
private final CacheManager level1; // 本地缓存
private final CacheManager level2; // Redis缓存
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<>();
public MultiLevelCacheManager(CacheManager level1, CacheManager level2) {
this.level1 = level1;
this.level2 = level2;
}
@Override
public Cache getCache(String name) {
return cacheMap.computeIfAbsent(name,
key -> new MultiLevelCache(
level1.getCache(name),
level2.getCache(name)
));
}
@Override
public Collection<String> getCacheNames() {
return Stream.concat(
level1.getCacheNames().stream(),
level2.getCacheNames().stream()
).collect(Collectors.toSet());
}
// 多级缓存实现
static class MultiLevelCache implements Cache {
private final Cache level1;
private final Cache level2;
private final String name;
public MultiLevelCache(Cache level1, Cache level2) {
this.level1 = level1 != null ? level1 : new NoOpCache();
this.level2 = level2 != null ? level2 : new NoOpCache();
this.name = level1.getName() + ":" + level2.getName();
}
@Override
public String getName() {
return name;
}
@Override
public Object getNativeCache() {
return this;
}
@Override
public ValueWrapper get(Object key) {
// 先查一级缓存
ValueWrapper value = level1.get(key);
if (value == null) {
// 二级缓存查询
value = level2.get(key);
if (value != null) {
// 回填一级缓存
level1.put(key, value.get());
}
}
return value;
}
@Override
public <T> T get(Object key, Class<T> type) {
// 实现逻辑类似get方法
T value = level1.get(key, type);
if (value == null) {
value = level2.get(key, type);
if (value != null) {
level1.put(key, value);
}
}
return value;
}
@Override
public void put(Object key, Object value) {
// 同时写入两级缓存
level1.put(key, value);
level2.put(key, value);
}
@Override
public void evict(Object key) {
// 同时清除两级缓存
level1.evict(key);
level2.evict(key);
}
@Override
public void clear() {
level1.clear();
level2.clear();
}
}
// 空缓存实现(容错)
static class NoOpCache implements Cache {
// 实现基础的Cache方法,返回空值
}
}
@Service
public class ProductService {
@Cacheable(value = "products", key = "#id")
public Product getProduct(Long id) {
// 数据库查询逻辑
return productRepository.findById(id)
.orElseThrow(() -> new NotFoundException("Product not found"));
}
@CacheEvict(value = "products", key = "#product.id")
public void updateProduct(Product product) {
productRepository.save(product);
}
}
spring:
cache:
multi-level:
level1:
ttl: 30s # 本地缓存时间
max-size: 1000
level2:
ttl: 5m # Redis缓存时间
redis:
host: redis-cluster.prod
port: 6379
timeout: 2000ms
@CacheEvict
)@PostConstruct
public void preloadHotData() {
// 加载热点数据到缓存
hotProducts.forEach(product ->
cacheManager.getCache("products").put(product.getId(), product));
}
@Bean
public MeterRegistryCustomizer<MeterRegistry> cacheMetrics() {
return registry -> {
CaffeineCacheManager caffeine = context.getBean(CaffeineCacheManager.class);
RedisCacheManager redis = context.getBean(RedisCacheManager.class);
// 注册Caffeine监控
CacheMetrics.monitor(registry, caffeine, "level1");
// 注册Redis监控
CacheMetrics.monitor(registry, redis, "level2");
};
}
// 在MultiLevelCache.get方法中添加
ValueWrapper get(Object key) {
try {
// 添加分布式锁检查
if (lockManager.tryLock(key)) {
// 实际查询逻辑
}
} finally {
lockManager.unlock(key);
}
}