在 Spring Boot 环境中,Redis 的 Value 序列化方式选择对系统性能、可维护性和兼容性有重要影响。下面我将介绍几种常见的序列化方案及其使用场景。
方案一:Jackson2JsonRedisSerializer(JSON 序列化)
适用场景
- 需要人类可读的数据格式
- 需要与其他语言或系统交互
- 数据结构复杂且经常变化
优缺点
优点:
- 可读性好
- 跨语言兼容性强
- 支持复杂对象结构
缺点:
- 序列化/反序列化性能一般
- 存储空间占用相对较大
使用示例
arduino
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 Jackson2JsonRedisSerializer 序列化 value
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
方案二:GenericJackson2JsonRedisSerializer(通用 JSON 序列化)
适用场景
- 需要存储多种类型对象
- 需要类型信息保留在 JSON 中
- 需要更好的兼容性
优缺点
优点:
- 自动添加类型信息
- 支持多态类型
- 兼容性好
缺点:
- JSON 中包含类型信息,体积稍大
- 性能略低于普通 Jackson 序列化
使用示例
arduino
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 GenericJackson2JsonRedisSerializer 序列化 value
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
方案三:JdkSerializationRedisSerializer(JDK 序列化)
适用场景
- 单一 Java 环境使用
- 对可读性要求不高
- 需要序列化复杂对象
优缺点
优点:
- 支持所有可序列化 Java 对象
- 实现简单
缺点:
- 数据不可读
- 跨语言兼容性差
- 序列化后数据体积较大
使用示例
arduino
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 JdkSerializationRedisSerializer 序列化 value
JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
方案四:StringRedisSerializer(字符串序列化)
适用场景
- 存储简单字符串或已序列化的数据
- 需要手动控制序列化过程
- 性能要求极高的场景
优缺点
优点:
- 性能最好
- 存储空间最小
缺点:
- 需要手动处理对象序列化
- 不支持复杂对象直接存储
使用示例
arduino
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 所有值都作为字符串处理
template.setValueSerializer(new StringRedisSerializer());
template.setHashValueSerializer(new StringRedisSerializer());
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
// 使用时需要手动序列化对象
@Component
public class UserService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private ObjectMapper objectMapper;
public void saveUser(User user) throws JsonProcessingException {
String userJson = objectMapper.writeValueAsString(user);
redisTemplate.opsForValue().set("user:" + user.getId(), userJson);
}
public User getUser(String id) throws JsonProcessingException {
String userJson = redisTemplate.opsForValue().get("user:" + id);
return objectMapper.readValue(userJson, User.class);
}
}
总结与建议
-
通用场景 :推荐使用
GenericJackson2JsonRedisSerializer
,它在类型安全性和可读性之间取得了良好平衡。 -
性能敏感场景 :如果主要是存储字符串或已序列化的数据,使用
StringRedisSerializer
并结合手动序列化可以获得最佳性能。 -
纯Java环境 :如果不需要与其他语言交互,可以使用
JdkSerializationRedisSerializer
,但要注意它可能导致较大的存储空间占用。 -
高性能要求:对于极端性能要求,考虑使用 Protobuf、Kryo 或 MessagePack 等二进制序列化方案。
-
最佳实践:
- Key 始终使用
StringRedisSerializer
- 根据实际需求选择合适的 Value 序列化器
- 考虑数据迁移成本,选择稳定的序列化方案
- 在分布式环境中,注意序列化兼容性问题
- Key 始终使用
6.我的选择
arduino
// 综合建议配置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 GenericJackson2JsonRedisSerializer 作为默认序列化器
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
template.setDefaultSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
根据实际项目需求,可以选择最适合的序列化方案,也可以在系统中同时使用多种序列化方式处理不同类型的数据。