在使用 Spring Boot 操作 Redis 的过程中,你是否遇到过这样的问题:
127.0.0.1:6379> keys *
"\xac\xed\x00\x05t\x00\r1751877165023"
你本来希望 key 是:
1751877165023
但实际却存成了一串看不懂的乱码二进制。这是怎么回事?本文将从原理、问题分析到解决方案,全面讲解这个现象的根本原因和处理方式。
一、问题背景
在 Java 项目中,我们通常使用 RedisTemplate 来操作 Redis。如果使用不当,key 和 value 可能会被以 JDK 默认序列化格式(即 JdkSerializationRedisSerializer)保存到 Redis 中,从而导致可读性差,甚至出现乱码。
二、现象复现
项目中代码如下:
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
public void save() {
redisTemplate.opsForValue().set(1751877165023L, "value");
}
然后你在 Redis 中查看 key:
127.0.0.1:6379> keys *
"\xac\xed\x00\x05t\x00\r1751877165023"
这是 Redis 中实际存储的 key,看起来完全不像你期望的字符串 1751877165023。
三、原因分析:JDK 默认序列化机制
我们可以做个测试:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
@SpringBootTest
public class Test {
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
RedisTemplate redisTemplate;
@org.junit.jupiter.api.Test
public void testSerializer(){
String KeySerializerName = stringRedisTemplate.getKeySerializer().getClass().getName();
System.out.println("stringRedisTemplate KeySerializerName = " + KeySerializerName);
System.out.println("stringRedisTemplate ValueSerializerName = " + stringRedisTemplate.getValueSerializer().getClass().getName());
String redisTemplateName = redisTemplate.getKeySerializer().getClass().getName();
System.out.println("redisTemplate KeySerializerName = " + redisTemplateName);
System.out.println("redisTemplate ValueSerializerName = " + redisTemplate.getValueSerializer().getClass().getName());
}
}
上述程序输出为:
stringRedisTemplate KeySerializerName = org.springframework.data.redis.serializer.StringRedisSerializer
stringRedisTemplate ValueSerializerName = org.springframework.data.redis.serializer.StringRedisSerializer
redisTemplate KeySerializerName = org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
redisTemplate ValueSerializerName = org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
可以看到,在默认情况下,RedisTemplate使用的是:
JdkSerializationRedisSerializer
它会将 Java 对象(包括 key 和 value)序列化为二进制格式:
| 字节序列 | 含义 |
|---|---|
\xac\xed | Java 序列化魔数(固定) |
\x00\x05 | 序列化版本号 |
t (0x74) | 类型代码,代表 Java 字符串 |
\x00\r | 字符串长度(13) |
1751877165023 | 实际字符串内容 |
这也是为什么 Redis 中 key 被转成了这样一串二进制编码,而不是你设置的纯字符串。
四、正确做法:设置 RedisTemplate 的序列化器
我们应该手动配置 RedisTemplate 的序列化策略,最常见的做法是:
- key / hashKey 使用
StringRedisSerializer - value / hashValue 使用 JSON 序列化器(如 Jackson、FastJSON2)
✅ 推荐配置示例:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// key 使用字符串序列化器
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// value 使用 JSON 序列化器(这里用 Jackson,也可替换为 FastJSON2)
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
配置完毕后,再次写入 Redis:
redisTemplate.opsForValue().set("1751877165023", "hello");
Redis 中 key 变成了可读字符串:
127.0.0.1:6379> keys *
"1751877165023"
六、如何查看 Redis 中真实存储内容?
你可以使用以下方式查看 Redis key 的真实格式:
1. redis-cli 命令行
keys *
如果看到 \xac\xed 开头的内容,说明用了 JDK 序列化。
2. 图形化工具
如 Redis Desktop Manager、Another Redis Desktop Manager (ARDM),能更直观地看到 key 和 value 的结构。
✍️ 最后
Redis 本是一个轻量级、可视化极强的 K/V 数据库,我们在 Java 中使用它时,不应让底层的序列化方式变成阻碍调试和跨语言交互的绊脚石。合理配置序列化器,既提高了效率,也提升了代码质量。
如果你还在用默认 RedisTemplate 或发现 Redis key 是乱码,建议立刻检查序列化配置。

1679

被折叠的 条评论
为什么被折叠?



