根本原因是spring data redis默认使用jdkserializationredisserializer等非字符串序列化器,将字符串key当作java对象序列化,产生乱码前缀或json引号包裹;正确做法是统一配置stringredisserializer处理所有键、值及hash结构字段,确保utf-8直通无包装。

Redis key 出现 "mykey" 而不是 mykey 的根本原因
不是 Redis 本身加的,也不是客户端命令行要求的——是 Spring Data Redis 在序列化 key 时用了非字符串序列化器(比如 JdkSerializationRedisSerializer 或 GenericJackson2JsonRedisSerializer),把原始字符串 mykey 当作 Java 对象处理,序列化后写入 Redis 的二进制内容里带了类型头、JSON 引号或 Java 序列化标记。你用 redis-cli 看到的 "mykey",其实是反序列化失败后 raw bytes 的“可读近似显示”,本质是乱码前缀 + 原字符串被包裹在 JSON 双引号中。
StringRedisSerializer 是最直接的解法,但必须配对使用
它不做任何包装,serialize("mykey") → byte[] 就是 UTF-8 编码的 mykey 本身;deserialize(bytes) 也只做 UTF-8 解码。但它只适用于纯字符串场景,一旦 value 是对象,就不能只设 value 序列化器而漏掉 hashKey / hashValue / setKey 等其他字段。
- 必须显式覆盖所有相关序列化器:
setKeySerializer、setValueSerializer、setHashKeySerializer、setHashValueSerializer - 若只改
keySerializer而 value 还用GenericJackson2JsonRedisSerializer,value 仍会多出双引号 - Spring Boot 2.4+ 默认自动配置的
redisTemplate是RedisTemplate<object object></object>,泛型不匹配会导致你自定义的 Bean 不被注入——要用@Primary或重命名 Bean 并在@Autowired时指定名称
为什么 stringRedisTemplate 天然不带双引号?
因为它的默认实现就是全链路用 StringRedisSerializer:RedisTemplate<string string></string>,key 和 value 都走字符串直通。但注意:它不能直接存 User 这类对象——会报 ClassCastException。如果你需要存对象又不想 JSON 包裹,就得自己封装:先用 ObjectMapper 转成 String,再交给 stringRedisTemplate 存;读取时手动反序列化。这不是“省事”,而是明确放弃框架自动序列化的隐式行为。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
已写入的带双引号 key 怎么清理?
不能靠 DEL mykey,得用实际存储的字节形式删除。例如,如果 key 是被 GenericJackson2JsonRedisSerializer 写入的,真实 key 是 "mykey"(含两个英文双引号字符),那么删除命令必须是:
DEL "\"mykey\""
在 shell 中需转义;在 Java 里用 redisTemplate.delete("\"mykey\"");批量时建议用 SCAN + Lua 脚本,且 pattern 要匹配带引号的原始形态。更稳妥的做法是:先用 redis-cli --scan --pattern '*' 导出所有 key,人工过滤出带引号的,再生成带转义的 DEL 命令列表,用 --pipe 批量执行。
关键点在于:序列化器一旦选错,写进去的数据就“定型”了;修复配置只能管住新数据,旧数据得按它真实的字节形态去操作,跳过任何中间解析层。










