二级缓存架构(Caffeine+Redis)
时间: 2025-06-28 14:15:12 浏览: 20
### 使用 Caffeine 和 Redis 构建二级缓存架构的设计与实现
#### 1. 添加依赖项
为了在项目中集成 Caffeine 和 Redis,需添加相应的依赖。对于 Maven 用户来说,可以在 `pom.xml` 文件中引入如下依赖:
```xml
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.0.5</version>
</dependency>
<!-- Spring Data Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
```
上述配置确保了项目的构建环境支持这两种技术栈[^1]。
#### 2. 创建并初始化 Caffeine 缓存实例
利用 `Caffeine.newBuilder()` 方法创建一个新的 Caffeine 缓存实例,并对其进行必要的参数设定,比如最大容量、过期策略等:
```java
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
public class CacheConfig {
private static final int MAX_SIZE = 10_000;
private static final long EXPIRE_AFTER_WRITE_DURATION = 1L;
public static LoadingCache<String, Object> caffeineCache = Caffeine.newBuilder()
.maximumSize(MAX_SIZE)
.expireAfterWrite(EXPIRE_AFTER_WRITE_DURATION, TimeUnit.HOURS)
.build(key -> loadFromDatabaseOrRedis(key));
}
```
这段代码定义了一个具有固定大小上限及写入后自动失效特性的本地内存缓存。
#### 3. 定义数据加载逻辑
当尝试访问不存在于任何一层缓存中的键时,默认情况下会触发此方法执行以填充缺失条目。这里假设存在一个名为 `loadFromDatabaseOrRedis(String key)` 的函数负责从持久化层读取所需资源;实际应用中应替换为此处省略的具体业务处理流程。
#### 4. 封装双重检查机制
每当请求到达服务器端口时,都会经历一次双层验证过程——即先查询快速响应的一级缓存(Caffeine),再转向较慢但更稳定的二级缓存(Redis)直至最终回退至原始数据源(如关系型数据库):
```java
@Service
@Slf4j
public class DualCheckService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 双重校验获取图片分页列表.
*/
public Page<PictureVO> getPicturePage(PageQuery pageQuery){
// 获取唯一标识符作为key
String cacheKey = buildCacheKey(pageQuery);
try{
// 尝试从一级缓存(Caffeine)中查找记录
Optional<Object> optionalLocalResult = Optional.ofNullable(CacheConfig.caffeineCache.getIfPresent(cacheKey));
if (!optionalLocalResult.isPresent()){
log.info("未命中一级缓存");
// 若不成功则转而向二级缓存发起检索命令
ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
String cachedValueFromRedis = opsForValue.get(cacheKey);
if (cachedValueFromRedis != null && !"".equals(cachedValueFromRedis)){
log.info("命中二级缓存");
// 更新到一级缓存以便后续更快捷地提供服务
CacheConfig.caffeineCache.put(cacheKey,cachedValueFromRedis);
return JSONUtil.toBean(cachedValueFromRedis,new TypeReference<Page<PictureVO>>() {});
}
log.warn("未能找到有效缓存,准备调用DB接口...");
// 当两轮搜索均失败后才允许直接连接到底层存储设备上进行实时计算
Page<PictureVO> dbResult = pictureMapper.selectByPage(pageQuery);
// 同步更新两个级别的缓存副本以防下次遇到相同情况仍需重复劳动
updateBothLevelCache(dbResult,cacheKey);
return dbResult;
}
log.debug("直接返回一级缓存的结果.");
return JSONUtil.toBean((String)optionalLocalResult.get(),new TypeReference<Page<PictureVO>>() {});
}catch(Exception e){
throw new RuntimeException(e.getMessage());
}
}
}
```
以上实现了基于 Caffeine 和 Redis 组合而成的高效能二级缓存解决方案,在保证高并发场景下的良好表现的同时也兼顾到了系统的稳定性和可靠性[^5]。
#### 5. 数据同步更新策略
考虑到一致性问题的存在,建议采用合理的刷新算法来保持各级别间的数据一致。一种常见做法是在每次修改操作完成后立即通知所有关联节点清除对应位置上的陈旧版本,随后按照既定规则重新加载最新状态的信息入库保存。
---
阅读全文
相关推荐



















