Redis是一个流行的内存数据库,它提供了多种数据结构和功能。其中一个关键特性是能够将数据序列化并存储在内存中。
Redis序列化器的作用是将数据从内存中的对象转换为字节流,并在需要时将其反序列化回对象。这样,我们就可以在Redis中存储和检索各种类型的数据,如字符串、哈希、列表等。
由于Redis内部不提供Java对象的存储格式,因此当操作的数据以对象的形式存在时,会进行转码,转换成字符串格式后进行操作,此时就需要序列化器帮我们完成。
Springboot中使用RedisTemplate操作默认序列化器是JdkSerializationRedisSerializer(没有配置的话)。
源码如下:
if (this.defaultSerializer == null) {
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
if (this.enableDefaultSerializer) {
if (this.keySerializer == null) {
this.keySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.valueSerializer == null) {
this.valueSerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashKeySerializer == null) {
this.hashKeySerializer = this.defaultSerializer;
defaultUsed = true;
}
if (this.hashValueSerializer == null) {
this.hashValueSerializer = this.defaultSerializer;
defaultUsed = true;
}
}
但是它有两个主要缺点:
序列化后的字节数组较大:JdkSerializationRedisSerializer使用Java的标准序列化机制,将对象序列化为字节数组。由于它会包含大量的Java类信息和字段描述,导致序列化后的字节数组较大。这会占用更多的内存空间,并且在网络传输时也会增加开销。
反序列化性能较低:JdkSerializationRedisSerializer的反序列化性能相对较低。由于它需要重新构建Java对象,包括加载类信息、解析字段等操作,这些操作会占用较多的CPU时间。因此,当需要频繁进行反序列化操作时,可能会影响系统的性能。
为了方便开发者使用基于字符串为数据的操作,Springboot提供了专用的API接口StringRedisTemplate(RedisTemplate子类)来操作Redis,可以理解为这是RedisTemplate的一种指定数据泛型的操作API。
@SpringBootTest
public class StringRedisTemplateTest {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void get(){
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
String name = ops.get("name");
System.out.println(name);
}
}
StringRedisTemplate所有数据转换使用的是StringRedisSerializer序列化器(键和值都是),有个缺点就是只能操作字符串数据。
源码如下:
public StringRedisTemplate() {
this.setKeySerializer(RedisSerializer.string());
this.setValueSerializer(RedisSerializer.string());
this.setHashKeySerializer(RedisSerializer.string());
this.setHashValueSerializer(RedisSerializer.string());
}
所以一般情况下,我们会选择自己写个配置类,配置自己想要的序列化器,高效操作Redis。
可以采用键序列化器选择StringRedisSerializer
值序列化器选择FastJsonRedisSerializer(是自己设计的序列化器)
当然也可以选择Springboot提供的Jackson2JsonRedisSerializer或GenericJackson2JsonRedisSerializer序列化器,它们基于Jackson库实现,在序列化和反序列化方面表现出色并且具有广泛的社区支持和广泛的应用,被广泛认可为Java开发中处理JSON的首选库。
根据实际需求、场景配置自己需要的序列化器:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
//FastJsonRedisSerializer 是自己设计的
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}