Redis序列化选型及应用

北城以北 提交于 2019-12-19 11:11:30

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

前言

序列化的含义、意义及使用场景

  • 序列化:将对象写入到IO流中
  • 反序列化:从IO流中恢复对象
  • 意义:序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
  • 使用场景:所有可在网络上传输的对象都必须是可序列化的,比如RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的java对象都必须是可序列化的。通常建议:程序创建的每个JavaBean类都实现Serializeable接口。

Redis序列化Spring Data实现

Spring-data-redids提供RedisSerializer接口用于Redis序列化实现,具体分为以下几种实现

JdkSerializationRedisSerializer

  1. RedisTemplate默认序列化
  2. 优点:
    1. 通用性强
    2. 反序列化时不需要提供类型信息(class)
  3. 缺点:
    1. 序列化速度慢
    2. 序列化占用内存大
    3. 序列化对象必须实现Serializable接口
    4. 可读性差
  4. 注意事项:
    1. 使用JdkSerializationRedisSerializer序列化的Bean必须实现Serializable接口

StringRedisSerializer

  1. StringRedisTemplate默认序列化
  2. 优点:
    1. 可读性强
    2. 不需要转换
  3. 缺点:
    1. 只能对字符串序列化
    2. 不能对对象序列化

GenericToStringSerializer

同StringRedisSerializer一样,但它可以将任何对象泛化为字符串并序列化。

注意事项:GenericToStringSerializer需要调用者给传一个对象到字符串互转的Converter,使用起来其比较麻烦,所以不太推荐使用。

Jackson2JsonRedisSerializer

  1. 使用Jackson库将对象序列化为JSON字符串。
  2. 优点:
    1. 速度快
    2. 序列化后的字符串短小精悍
    3. 不需要实现Serializable接口
  3. 缺点:
    1. 必须提供要序列化对象的类型信息(.class对象)

GenericJackson2JsonRedisSerializer

  1. 底层使用Jackson进行序列化并存入Redis。对于普通类型(如数值类型,字符串)可以正常反序列化回相应对象。
  2. 存入对象时由于没有存入类信息,则无法反序列化。

OxmSerializer

  1. 以xml格式存储(但还是String类型哦),解析起来也比较复杂。
  2. 缺点:
    1. 速度慢
    2. 占用空间大

ByteArrayRedisSerializer

Byte数组序列化

Redis序列化扩展实现

FastJsonRedisSerializer

  1. 由阿里巴巴FastJson包提供
  2. 优点: 1,速度快 2. 兼容性强 3. 占用内存小
  3. 缺点:暂无

GenericFastJsonRedisSerializer

同FastJsonRedisSerializer类似

KryoRedisSerializer

  1. 优点:
    1. 序列化速度极快
    2. 占用体积小
  2. 缺点:
    1. 非线程安全
    2. 跨语言支持较复杂

ProtoStuffRedisSerializer

  1. 优点:
    1. 序列化速度极快
    2. 占用体积小
  2. 缺点:
    1. 必须保证对象中字段顺序,否则会导致反序列化赋值错误
    2. 序列化对象不能删除字段,否则会导致反序列化失败

常见的的序列化反序列方式的效率:

protoBuf(PB) > fastjson > jackson > hessian > xstream > java

数据来自于:https://github.com/eishay/jvm-serializers/wiki

总结

推荐使用StringRedisSerializer作为Key序列化,使用FastJsonRedisSerializer作为Value序列化。

代码实现

  1. 引入maven包依赖
<!-- Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>
<!-- FastJson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
  1. 配置类RedisAutoConfiguration.java
private void setSerializer(RedisTemplate<String, Object> redisTemplate) {
    //设置键(key)的序列化方式
    FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
    // 全局开启AutoType,不建议使用
    // ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    // 建议使用这种方式,小范围指定白名单
    ParserConfig.getGlobalInstance().addAccept("com.xxx.");

    // 设置键(key)的序列化采用StringRedisSerializer。
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    // 设置值(value)的序列化采用FastJsonRedisSerializer。
    redisTemplate.setValueSerializer(fastJsonRedisSerializer);
    redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
    redisTemplate.afterPropertiesSet();
}

注意事项

参考文献

java序列化,看这篇就够了

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!