Redis key值出现不可见字符的原因分析及解决

作者:技术拾光时间:2026-06-11 08:54:07浏览:165

RedisKey乱码因SpringRedisTemplate默认JDK序列化,生成含0xAC、0xED魔数的字节流,导致Redis客户端无法识别。自定义RedisTemplate,将key序列化器改为StringRedisSerializer,以纯文本形式存储键,即可解决乱码问题。

Redis Key 莫名出现 xACxEDx00x05tx00x19 ?问题出在这

使用 Spring RedisTemplate 向 Redis 存储数据时,有时会发现 key 变成了一串乱码,例如 xACxEDx00x05tx00、xACxEDx00x05tx00x19、xACxEDx00x05tx00x11。这种现象通常由序列化机制引起,本文将拆解原因并给出有效解决方案,帮助开发者解决 Redis key 乱码问题。

Redis key值出现不可见字符的原因分析及解决

1. 先看 Spring Data Redis 的源代码

核心类 org.springframework.data.redis.core.RedisTemplate 的源码中隐藏着答案:

Redis key值出现不可见字符的原因分析及解决

2. 底层用的是 Jedis 客户端,而 Jedis 默认处理 byte[]

Spring 操作 Redis 底层依赖 Jedis 客户端,Jedis 与 Redis 交互时,协议规定使用 byte 数组 传输数据。Jedis 本身提供了 String 转 byte[] 的方法,但 Spring 的 RedisTemplate 的 key 和 value 都是泛型,因此 Spring 默认采用 JdkSerializationRedisSerializer 进行序列化。进一步查看 JdkSerializationRedisSerializer 的序列化逻辑,可以找到关键代码:

Redis key值出现不可见字符的原因分析及解决

3. 序列化默认是针对 Object 对象的

它调用了 SerializingConverter 的 convert 方法,将任意对象转换为字节流。具体转换逻辑如下:

Redis key值出现不可见字符的原因分析及解决

4. 问题就出在这里

默认使用 Java 原生序列化,生成的字节流头部为 0xAC 0xED(Java 序列化魔数),后面跟着完整的对象描述信息。存入 Redis 后,key 自然显示为乱码。

解决办法是 手动指定序列化方式。Spring Data Redis 提供了 StringRedisSerializer 专门处理 String 类型的 key。可以在带有 @Configuration 注解的类中,覆盖自动配置的 RedisTemplate,示例如下:

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
    RedisTemplate redisTemplate = new RedisTemplate<>();
    // 设置 redis 连接
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    // 使用 Jackson2JsonRedisSerialize 替换默认序列化
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    // 设置 value 的序列化规则和 key 的序列化规则
    redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    // 将 key 的序列化方式改为 StringRedisSerializer
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

配置完成后,重新存入新的 key,查询结果将恢复正常:

Redis key值出现不可见字符的原因分析及解决

总结

问题的根本原因是 Spring 默认使用 JDK 序列化方式处理 key,而 JDK 序列化输出的字节流包含完整的 Java 对象头部信息,导致 key 在 Redis 中呈现乱码。解决思路是自定义 RedisTemplate,将 key 的序列化器替换为 StringRedisSerializer,同时 value 也可以改用更友好的 JSON 序列化。这样既能保证可读性,又能有效避免 Redis key 乱码问题。