针对不同使用场景,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;
    }
}

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

相关推荐
郭俊强1 小时前
nestjs 连接redis
数据库·redis·缓存
_風箏3 小时前
SpringBoot【集成Thumbnailator】Google开源图片工具缩放+区域裁剪+水印+旋转+保持比例等(保姆级教程含源代码)
spring boot·后端·google
鱼骨不是鱼翅3 小时前
redis---set详解
redis
工业甲酰苯胺3 小时前
Redis支持事务吗?了解Redis的持久化机制吗?
数据库·redis·bootstrap
kong@react5 小时前
docker部署spring boot,安装jdk17、maven3.8.8详细步骤
java·spring boot·docker
AscentStream5 小时前
如何基于 SpringBoot 快速构建 Apache Pulsar 实时应用
spring boot
zhz52147 小时前
从PostgreSQL到人大金仓(KingBase)数据库迁移实战:Spring Boot项目完整迁移指南
数据库·spring boot·postgresql
万行8 小时前
点评项目(Redis中间件)&第一部分Redis基础
java·数据库·redis·缓存·中间件
Seven978 小时前
一文带你了解缓存和数据库一致性问题
redis·mysql