Spring Redis Template写入Redis Hash后Golang Redis v9读取乱码排查
问题描述
我们的架构通过Spring Redis Template向AWS Redis写入Hash数据,当前尝试使用github.com/redis/go-redis/v9 v9.3.1版本的Golang SDK读取该Hash。
读取代码
val, err := redisClient.HGet(ctx, "user_chats", userId).Result() switch { case err == redis.Nil: log.Println("key does not exist") case err != nil: log.Fatal("Get failed", err) case val == "": fmt.Println("value is empty") } result, err := redisClient.HGetAll(ctx, "user_chats").Result() if err != nil { log.Println("Error getting all chat ids for user", err) } fmt.Println("Result is", result) s := result[userId] return s }
异常输出
当调用HGetAll打印整个Hash时,结果出现乱码字符:
Result is map[user:100:hahaah ��tu168473538491428454250:��srjava.util.ArrayListx����a�Isizexpwtpc-85465830822572tpc-94681574924616tpc-1396801104467750tpc-962866567187043t gp12973943794tgp816559870050427tgp875663326163364x]
请问该问题是由写入数据的Spring Redis Template导致,还是由负责读取的Golang Redis驱动导致?
问题分析与结论
这个问题完全由Spring Redis Template的默认序列化方式导致,和Golang的go-redis驱动无关:
- Spring Redis Template默认采用
JdkSerializationRedisSerializer,会将Java对象(比如示例中的ArrayList)序列化为JDK专属的二进制格式,其中包含Java类元数据(如srjava.util.ArrayList这类标识)和不可打印的二进制字节,这些内容在Golang直接读取时就会显示为乱码(即你看到的��)。 - Golang的
go-redisSDK只是按原始字节读取Redis中的数据,没有对应的JDK反序列化逻辑,所以会把二进制内容直接输出为乱码字符。
解决建议
- 若要实现跨语言(Java+Golang)兼容读取,Spring侧需替换序列化方式为JSON序列化,比如配置
Jackson2JsonRedisSerializer,这样写入Redis的是标准JSON格式,Golang侧可直接解析为对应结构体或字符串。 - 若无法修改写入逻辑,Golang侧需要实现JDK序列化的反解析逻辑,但该方式复杂度极高,不推荐使用。
内容的提问来源于stack exchange,提问作者MrWayne
相关产品推荐
相关产品推荐

