针对不同使用场景,Redis的Value应该如何序列化,优缺点如何,进来看

在 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);
    }
}

总结与建议

  1. 通用场景 :推荐使用 GenericJackson2JsonRedisSerializer,它在类型安全性和可读性之间取得了良好平衡。

  2. 性能敏感场景 :如果主要是存储字符串或已序列化的数据,使用 StringRedisSerializer 并结合手动序列化可以获得最佳性能。

  3. 纯Java环境 :如果不需要与其他语言交互,可以使用 JdkSerializationRedisSerializer,但要注意它可能导致较大的存储空间占用。

  4. 高性能要求:对于极端性能要求,考虑使用 Protobuf、Kryo 或 MessagePack 等二进制序列化方案。

  5. 最佳实践

    • Key 始终使用 StringRedisSerializer
    • 根据实际需求选择合适的 Value 序列化器
    • 考虑数据迁移成本,选择稳定的序列化方案
    • 在分布式环境中,注意序列化兼容性问题

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;
    }
}

根据实际项目需求,可以选择最适合的序列化方案,也可以在系统中同时使用多种序列化方式处理不同类型的数据。

相关推荐
我叫张小白。13 小时前
Spring Boot拦截器详解:实现统一的JWT认证
java·spring boot·web·jwt·拦截器·interceptor
q***697715 小时前
Spring Boot与MyBatis
spring boot·后端·mybatis
m***567215 小时前
Win10下安装 Redis
数据库·redis·缓存
r***123816 小时前
SpringBoot最佳实践之 - 使用AOP记录操作日志
java·spring boot·后端
LSL666_17 小时前
SpringBoot自动配置类
java·spring boot·后端·自动配置类
q***783717 小时前
Spring Boot 3.X:Unable to connect to Redis错误记录
spring boot·redis·后端
t***265918 小时前
SpringBoot + vue 管理系统
vue.js·spring boot·后端
qq_124987075319 小时前
基于springboot的疾病预防系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
q***25120 小时前
Spring Boot 集成 Kettle
java·spring boot·后端
SoleMotive.21 小时前
redis实现漏桶算法--https://blog.csdn.net/m0_74908430/article/details/155076710
redis·算法·junit