一、核心架构图解
二、关键组件解析
1. 缓存注解与Redis映射
@Cacheable(value = "users", key = "#id")
public User getUser(Long id) { ... }
- Redis键生成:
cacheName::SpEL表达式结果
- 值序列化:默认使用JDK序列化,推荐JSON
2. RedisCacheManager配置
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofMinutes(30));return RedisCacheManager.builder(factory).cacheDefaults(config).build();
}
三、数据存储结构
1. Redis数据结构
# String类型存储
SET "users::1001" "{\"id\":1001,\"name\":\"Alice\"}"# Hash类型存储(当使用@Cacheable的cacheNames多级时)
HSET "users" "1001" "{\"id\":1001,\"name\":\"Alice\"}"
2. TTL管理
四、缓存操作流程
五、高级特性实现
1. 缓存穿透防护
@Cacheable(value = "users", key = "#id", unless = "#result == null")
public User getUser(Long id) { // 返回null时不缓存
}
2. 分布式锁同步
@CachePut(value = "users", key = "#user.id")
@Transactional
public User updateUser(User user) {// 使用Redisson实现分布式锁RLock lock = redissonClient.getLock("user_lock:" + user.getId());try {lock.lock();// 业务逻辑} finally {lock.unlock();}
}
六、性能优化策略
1. 序列化优化
@Bean
public RedisTemplate<String, Object> redisTemplate() {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());return template;
}
2. 批量操作
@Cacheable(value = "users", keyGenerator = "batchKeyGenerator")
public List<User> batchGetUsers(List<Long> ids) {// 使用Redis管道批量获取
}
七、监控与故障排查
1. 缓存命中率统计
Cache cache = cacheManager.getCache("users");
RedisCacheStatistics stats = ((RedisCache) cache).getStatistics();
System.out.println("命中率: " + stats.getHitRatio());
2. 常见问题排查表
现象 | 可能原因 | 解决方案 |
---|---|---|
缓存数据不一致 | 未正确使用@CacheEvict | 添加事务管理,确保先更新数据库再清除缓存 |
反序列化失败 | 序列化方式不一致 | 统一客户端和服务端的序列化配置 |
内存溢出 | 未设置TTL或内存淘汰策略 | 配置合理的过期时间和LRU淘汰策略 |
高延迟 | 大Value值存储 | 压缩数据或拆分存储 |
通过合理配置Spring Cache与Redis的集成,可以实现:
- 透明化缓存管理:业务代码无需关注缓存实现
- 高性能数据访问:减少数据库压力
- 分布式一致性:通过Redis实现多节点缓存同步
- 灵活的策略配置:按需定制过期时间、序列化方式等
实际应用中需注意:
- 避免过度缓存导致内存压力
- 保持缓存与数据源的一致性
- 监控缓存命中率和响应时间
- 定期进行缓存清理和维护