Spring Boot 操作 Redis 时 KeySerializer 和 HashKeySerializer 有什么区别?
在使用 Spring Data Redis 时,我们通常会设置 RedisTemplate
的序列化方式。其中,两个很容易混淆的配置是:
KeySerializer
HashKeySerializer
这两个序列化器看起来名字相似,但作用却完全不同。本文将从实际使用场景出发,带你彻底搞清楚这两个参数的含义与使用方式。
📌 一句话概括区别
名称 | 应用场景 | 用途说明 |
---|---|---|
KeySerializer | 普通 K/V 结构的 key,如 set("k", "v") | 序列化最外层 Redis 键(key) |
HashKeySerializer | Redis Hash 结构中的字段名,如 hset("hash", "field", "value") | 序列化 Hash 内部的字段名(field) |
✅ 示例解释
下面我们用两个典型的 Redis 数据结构来展示它们分别在什么场景下生效。
1. 普通 Key-Value 操作
redisTemplate.opsForValue().set("user:1", "zhangsan");
在这个操作中:
元素 | 对应序列化器 |
---|---|
"user:1" | KeySerializer |
"zhangsan" | ValueSerializer |
2. Hash 类型操作
redisTemplate.opsForHash().put("user:1", "name", "zhangsan");
在这个操作中:
元素 | 对应序列化器 |
---|---|
"user:1" | KeySerializer |
"name" | HashKeySerializer |
"zhangsan" | HashValueSerializer |
❗为什么要特别设置 HashKeySerializer?
如果不手动配置 HashKeySerializer
,RedisTemplate 会默认使用 JdkSerializationRedisSerializer
【详情可见笔者的另一篇博客Java JDK 默认序列化问题详解与解决方案】,这会导致 Redis 中的字段名变成不可读的二进制乱码:
127.0.0.1:6379> hgetall user:1
1) "\xac\xed\x00..." <-- 乱码
2) "zhangsan"
配置后变为可读字符串:
127.0.0.1:6379> hgetall user:1
1) "name"
2) "zhangsan"
✅ 正确配置方式
推荐配置 RedisTemplate 的四种序列化方式如下:
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 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;}
}
📌 总结对比表
序列化器名称 | 应用位置 | 是否必须设置 | 推荐值 |
---|---|---|---|
KeySerializer | Redis 的最外层 key,如 "user:1" | ✅ 是 | StringRedisSerializer |
ValueSerializer | 普通键值结构的 value,如 "zhangsan" | ✅ 是 | JSON 序列化器 |
HashKeySerializer | Hash 内字段名(field),如 "name" | ✅ 是 | StringRedisSerializer |
HashValueSerializer | Hash 内字段值,如 "zhangsan" | ✅ 是 | JSON 序列化器 |
✅ 使用建议
- 四个序列化器都要手动配置,不要依赖默认值
- 建议统一使用
StringRedisSerializer
+GenericJackson2JsonRedisSerializer
,可读性强、兼容性好
✍写在最后
Redis 是一个轻量、高性能、跨语言的缓存中间件。在 Java 项目中合理配置 RedisTemplate 的序列化方式,不仅能提升可读性和调试体验,也能避免数据不兼容和乱码问题。希望本文能帮助你从源头上理解 KeySerializer
与 HashKeySerializer
的本质区别。