本地缓存架构
本地缓存架构
Caffeine缓存
Caffeine采用W-TinyLFU算法,在近乎最优的命中率下提供接近O(1)的读写性能。
@Configuration
public class CaffeineConfig {
@Bean
public Cache<String, Object> caffeineCache() {
return Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(30, TimeUnit.MINUTES)
.recordStats()
.build();
}
@Bean
public LoadingCache<String, UserDTO> userCache() {
return Caffeine.newBuilder()
.maximumSize(5_000)
.expireAfterAccess(10, TimeUnit.MINUTES)
.refreshAfterWrite(5, TimeUnit.MINUTES)
.build(key -> userRepository.findById(key).orElse(null));
}
}
Guava Cache
Guava Cache提供灵活的过期策略和 eviction 监听,适合需要精细控制的场景。
@Bean
public Cache<String, ProductDTO> productCache() {
return CacheBuilder.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(30, TimeUnit.MINUTES)
.removalListener(notification ->
log.info("Key {} removed, cause: {}", notification.getKey(), notification.getCause()))
.build(new CacheLoader<>() {
@Override
public ProductDTO load(String key) {
return productRepository.findById(key).orElse(null);
}
});
}
多级缓存整合
本地缓存作为L1层,Redis作为L2层,数据库作为L3层,实现分层过滤。
@Service
public class TwoLevelCacheService {
private final Cache<String, Object> localCache;
private final RedisTemplate<String, Object> redisTemplate;
public Object get(String key) {
Object value = localCache.getIfPresent(key);
if (value != null) return value;
value = redisTemplate.opsForValue().get(key);
if (value != null) {
localCache.put(key, value);
return value;
}
value = loadFromDB(key);
if (value != null) {
redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
localCache.put(key, value);
}
return value;
}
public void evict(String key) {
localCache.invalidate(key);
redisTemplate.delete(key);
}
}
Caffeine vs Guava对比
| 特性 | Caffeine | Guava |
|---|---|---|
| 算法 | W-TinyLFU | LRU/LFU |
| 性能 | 更高 | 良好 |
| 异步刷新 | 支持 | 不支持 |
| 监控统计 | 内置 | 需额外配置 |