Spring Data Redis基础

基本组件

RedisTemplate 核心模板类,封装 Redis 所有操作(字符串、哈希、列表等) 类似 Spring 的 JdbcTemplate,提供泛型支持,可自定义序列化方式

StringRedisTemplate 专门处理字符串类型的模板类,是 RedisTemplate<String, String> 的子类 默认使用 StringRedisSerializer,无需额外配置,适合绝大多数字符串场景

RedisConnectionFactory 连接工厂,负责创建和管理 Redis 连接,是 RedisTemplate 的依赖核心 主流实现:LettuceConnectionFactory(推荐,非阻塞)、JedisConnectionFactory(传统,阻塞)

RedisSerializer 序列化 / 反序列化器,负责将 Java 对象与 Redis 存储的二进制数据相互转换 解决 Java 对象直接存储到 Redis 的 "序列化乱码" 问题,提供多种内置实现

ValueOperations 操作 Redis 字符串(String)类型的 API 接口 由 RedisTemplate 或 StringRedisTemplate 通过 opsForValue() 获取

HashOperations 操作 Redis 哈希(Hash)类型的 API 接口 通过 opsForHash() 获取,支持键值对嵌套存储

ListOperations 操作 Redis 列表(List)类型的 API 接口 通过 opsForList() 获取,支持链表的增删改查(如左插、右插、范围查询)

SetOperations 操作 Redis 集合(Set)类型的 API 接口 通过 opsForSet() 获取,支持交集、并集、差集等集合运算

ZSetOperations 操作 Redis 有序集合(Sorted Set)类型的 API 接口 通过 opsForZSet() 获取,支持按分数排序、范围查询、分数更新等

自定义 RedisTemplate 配置

由于Spring Boot 默认提供的 RedisTemplate 使用 JdkSerializationRedisSerializer,会导致 Redis 中存储的键值带有序列化前缀,需要自定义序列化方式( StringRedisSerializer处理键,GenericJackson2JsonRedisSerializer处理值):

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(factory);
        
        // 序列化配置:键用 String 序列化,值用 JSON 序列化
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer valueSerializer = new GenericJackson2JsonRedisSerializer();
        
        template.setKeySerializer(keySerializer);        // 键序列化
        template.setValueSerializer(valueSerializer);      // 值序列化
        template.setHashKeySerializer(keySerializer);     // 哈希键序列化
        template.setHashValueSerializer(valueSerializer); // 哈希值序列化
        
        // 初始化模板
        template.afterPropertiesSet();
        return template;
    }
}

常见问题

序列化乱码:未自定义 RedisTemplate 的序列化器,默认使用 JdkSerializationRedisSerializer,需替换为 StringRedisSerializer + GenericJackson2JsonRedisSerializer。

连接池耗尽:未配置连接池参数或操作后未释放连接(RedisTemplate会自动释放)。

缓存穿透:查询不存在的 key 导致每次都查数据库,解决方案:缓存空值、布隆过滤器。

缓存击穿:热点 key 过期瞬间大量请求查数据库,解决方案:互斥锁、热点 key 永不过期。

缓存雪崩:大量 key 同时过期导致数据库压力骤增,解决方案:key 过期时间加随机值、集群部署 Redis。

实践方案

优先使用 StringRedisTemplate:绝大多数场景是字符串操作,无需额外序列化配置,性能更高。

合理设置过期时间:避免 Redis 内存溢出,通过 expire() 或 set(key, value, timeout) 设置过期时间。

键名规范:使用 "业务:模块:ID" 格式,便于维护和排查。

避免大 key:大 key 会导致 Redis 性能下降,需拆分。

选择 Lettuce 客户端:Lettuce 基于 Netty 实现,支持非阻塞 IO,性能优于传统的 Jedis(阻塞 IO),是 Spring Boot 默认客户端。