redis存字符串出现\x00或\xaced\x00\x05等乱码前缀,是客户端序列化所致:python常见于pickle,java常见于jdkserializationredisserializer;应显式encode("utf-8")或配置stringredisserializer确保纯文本存储。

Redis 存入字符串时出现 \x00\x00\x00\x00\x00\x00\x00\x00 类乱码前缀
这是 Redis 客户端在序列化时自动加了协议头或用了非纯文本编码,最常见于 Python 的 pickle 序列化写入,或 Java 的 JdkSerializationRedisSerializer。Redis 本身不加前缀,是客户端干的。
- 检查你用的是不是
redis-py的默认ConnectionPool配置 +set()直接传对象(比如 dict/list)——它不会自动序列化,但如果你用了StrictRedis.from_url()搭配某些框架(如 Flask-Session),底层可能启用了 pickle - Java 项目里如果配置了
GenericJackson2JsonRedisSerializer却误配成JdkSerializationRedisSerializer,就会塞进二进制头 - Node.js 的
ioredis一般不会出这事,但若手动调了Buffer.from(obj)再存,且obj是未 toString() 的对象,也可能带不可见字节
Python redis-py 怎么确保存进去就是干净 UTF-8 字符串
核心原则:别让客户端替你序列化,自己控制编码。
- 写入前显式调用
str(my_data).encode("utf-8"),再传给r.set(key, ...) - 避免直接传
dict、list或自定义类实例——redis-py不会帮你转,会报TypeError: a bytes-like object is required;但如果用了某些封装库(如django-redis的 cache backend),它可能悄悄用了 pickle - 初始化 client 时加参数:
decode_responses=True只影响读取,不影响写入;真正要管写入,得自己 encode - 示例:
r.set("user:name", "张三".encode("utf-8")) # ✅ 干净r.set("user:name", "张三") # ✅ 也行,redis-py 会自动 encode,但仅限 str/bytesr.set("user:info", {"age": 25}) # ❌ 触发 TypeError,除非你开了 serializer
Java Spring Boot 中 RedisTemplate 存字符串带 \xac\xed\x00\x05 前缀
这是 Java 的 ObjectOutputStream 头部签名,说明用了 JdkSerializationRedisSerializer,哪怕你只 put 一个 String。
- 确认
RedisTemplate的valueSerializer是不是默认值——Spring Boot 2.0+ 默认是Jackson2JsonRedisSerializer,但老项目或手动配置容易漏掉 - 显式指定字符串专用 template:
@Bean public RedisTemplate<String, String> stringRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new StringRedisSerializer()); // 关键 return template; } - 别混用:
RedisTemplate和StringRedisTemplate是两个东西,后者默认就用StringRedisSerializer,更安全 - 如果必须存 JSON 对象,用
GenericJackson2JsonRedisSerializer,它输出纯文本,不带二进制头
如何快速验证当前 key 是否被序列化污染
不用查代码,直接用 redis-cli 或 GUI 工具看原始值。
- 命令行执行:
redis-cli GET your_key | xxd,如果开头是00000000或aced0005,基本确定是 pickle / JDK 序列化 - 在 RedisInsight 或 Another Redis Desktop Manager 里点开 key,切换到 “Hex” 视图,一眼能看见不可见字符
- 如果值是 JSON 但开头有
\u0000或乱码,大概率是写入时用了new String(byte[], charset)但 byte[] 来源不对(比如从网络流读了一半) - 注意:UTF-8 BOM(
\xef\xbb\xbf)也会表现为前缀,但它是合法的,只是多数 Redis 使用场景不需要
序列化策略一旦选错,读写两端必须严格对齐;很多人改了写入端却忘了清理旧数据,或者测试环境用 StringRedisTemplate、生产环境用默认 RedisTemplate,结果读出来全是乱码。这类问题往往不报错,只静默失效。










