在分布式系统或高并发场景下,数据库查询往往成为性能瓶颈。Redis 作为内存数据库,凭借其高速读写能力成为缓存的首选方案。本文将详细介绍如何在 Spring Boot 3.x 中整合 Redis,实现数据缓存、缓存穿透/雪崩防护等核心功能。
一、环境准备
- 技术栈 :
- Spring Boot 3.1.5
- Redis 7.0+
- JDK 17+
- Maven 3.8+
- 依赖配置 (
pom.xml):
xml
`<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 可选:用于序列化(如JSON) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
`
二、核心实现步骤
1. 配置 Redis 连接
在 application.yml 中配置 Redis 连接参数:
yaml
`spring:
redis:
host: localhost
port: 6379
password: yourpassword
database: 0
lettuce: # 连接池配置
pool:
max-active: 8
max-idle: 8
min-idle: 0
`
2. 配置 RedisTemplate 序列化方式
默认的 JDK 序列化会导致 key 显示乱码,推荐使用 String + JSON 序列化:
java
`@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// String 序列化
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// JSON 序列化(使用 Jackson)
Jackson2JsonRedisSerializer<Object> jsonSerializer =
new Jackson2JsonRedisSerializer<>(Object.class);
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
return template;
}
}
`
3. 封装通用缓存工具类
java
`@Component
public class RedisCacheUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 设置缓存(带过期时间)
public void set(String key, Object value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
// 获取缓存
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
// 删除缓存
public Boolean delete(String key) {
return redisTemplate.delete(key);
}
// 更多方法:Hash、List、Set 操作...
}
`
4. 使用 Spring Cache 注解(推荐)
在启动类添加 @EnableCaching 注解,然后通过注解简化缓存操作:
java
`@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// 从缓存获取,不存在则查询数据库并写入缓存
@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
// 更新缓存
@CachePut(value = "user", key = "#user.id")
public User updateUser(User user) {
return userRepository.save(user);
}
// 删除缓存
@CacheEvict(value = "user", key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
`
三、高级优化技巧
1. 防止缓存穿透
- 方案:使用空值缓存或布隆过滤器(Bloom Filter)。
- 示例:
java
`public User getUserByIdSafe(Long id) {
String key = "user:" + id;
Object cached = redisTemplate.opsForValue().get(key);
if (cached != null) {
if (cached instanceof User) return (User) cached;
return null; // 空值缓存
}
User user = userRepository.findById(id).orElse(null);
if (user != null) {
redisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);
} else {
// 空值缓存(防止穿透)
redisTemplate.opsForValue().set(key, "", 10, TimeUnit.MINUTES);
}
return user;
}
`
2. 防止缓存雪崩
- 方案 :
- 设置随机过期时间
- 使用多级缓存(本地缓存 + Redis)
- 示例:
java
`public void setWithRandomExpire(String key, Object value) {
int randomExpire = 3600 + new Random().nextInt(1800); // 1~1.5小时随机
redisTemplate.opsForValue().set(key, value, randomExpire, TimeUnit.SECONDS);
}
`
3. 分布式锁实现
java
`public boolean tryLock(String lockKey, String requestId, long expireTime) {
Boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS);
return Boolean.TRUE.equals(success);
}
public void unlock(String lockKey, String requestId) {
String value = (String) redisTemplate.opsForValue().get(lockKey);
if (requestId.equals(value)) {
redisTemplate.delete(lockKey);
}
}
`
四、常见问题排查
- 连接失败:检查 Redis 服务是否启动、防火墙设置、密码是否正确。
- 序列化异常 :确保所有缓存对象实现
Serializable接口或配置正确的序列化器。 - 注解不生效 :确认启动类添加了
@EnableCaching注解。
五、总结
通过 Spring Boot 整合 Redis,可以快速构建高性能缓存系统。合理使用缓存策略(如穿透/雪崩防护)能显著提升系统稳定性。完整代码示例已上传至 GitHub,欢迎 Star 和交流!