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 操作

java 复制代码
redisTemplate.opsForValue().set("user:1", "zhangsan");

在这个操作中:

元素 对应序列化器
"user:1" KeySerializer
"zhangsan" ValueSerializer

2. Hash 类型操作

java 复制代码
redisTemplate.opsForHash().put("user:1", "name", "zhangsan");

在这个操作中:

元素 对应序列化器
"user:1" KeySerializer
"name" HashKeySerializer
"zhangsan" HashValueSerializer

❗为什么要特别设置 HashKeySerializer?

如果不手动配置 HashKeySerializer,RedisTemplate 会默认使用 JdkSerializationRedisSerializer【详情可见笔者的另一篇博客Java JDK 默认序列化问题详解与解决方案】,这会导致 Redis 中的字段名变成不可读的二进制乱码

bash 复制代码
127.0.0.1:6379> hgetall user:1
1) "\xac\xed\x00..."  <-- 乱码
2) "zhangsan"

配置后变为可读字符串:

bash 复制代码
127.0.0.1:6379> hgetall user:1
1) "name"
2) "zhangsan"

✅ 正确配置方式

推荐配置 RedisTemplate 的四种序列化方式如下:

java 复制代码
@Configuration
public class RedisConfig {

    @Bean
    public 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 的序列化方式,不仅能提升可读性和调试体验,也能避免数据不兼容和乱码问题。希望本文能帮助你从源头上理解 KeySerializerHashKeySerializer 的本质区别。