背景:
最近考虑java代码数据在保存redis时,通常要配置序列化,才能保存到redis中,然而我们知道Redis中也有序列化(RDB和AoF两种形式),有点混淆总结一下。
java中数据保存redis过程序列化的原因是什么?
解释:
java虚拟机内存和redis内存是两块独立的内存空间,分属于两个不同的进程,不同的两个应用,在网络传输层表现为数据传输是用TCP二进制流进行传输的
序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。 而跨平台存储和网络传输的方式就是IO,而我们的IO支持的数据格式就是字节数组。
java中如何序列化?
package com.gisquest.cloud.oauth2.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfiguration {
private static final Logger logger = LoggerFactory.getLogger(RedisConfiguration.class);
@Autowired
private RedisProperties redisProperties;
@Bean
public RedisTemplate<Object, Object> redisTemplateOther(RedisConnectionFactory redisConnectionFactory) {
logger.info("redisProperties - host:[{}], port:[{}]",
redisProperties.getHost(), redisProperties.getPort());
RedisTemplate<Object,Object> redisTemplate=new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//使用Jackson2JsonRedisSerializer替换默认的序列化规则
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer=new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper=new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
//设置value的序列化规则
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
//设置key的序列化规则
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
项目中为什么常用用Jackson2JsonRedisSerializer序列化,而不用JdkSerializationRedisSerializer
Redis客户端存储对象时,需要通过序列化器将对象转化为字符串进行存储。默认情况下对象序列化器使用的是JdkSerializationRedisSerializer,该序列化器将对象转化byte数组进行存储。
由于默认序列化器需要存入对象必须实现Serializable接口,转化效率低及数据可读性差等问题存在,通常大部分项目会改用Jackson2JsonRedisSerializer或FastJsonRedisSerializer将对象转化为json进行序列化及反序列化。
redis为什么要持久化(序列化和反序列化)
主要是防止写入redis内存数据丢失。
Redis持久化的方式:快照、AOF日志
快照RDB(默认)与AOF各自特点:
快照是一次全量备份,AOF日志是连续的增量备份
快照是内存数据的二进制序列化形式,在存储上非常紧凑,而AOF日志记录的是内存数据修改的指令记录文本
AOF日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载AOF日志进行指重放,这个时间就会无比漫长,定期需要对AOF重写,使其瘦身。