前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis 与序列化

Redis 与序列化

作者头像
业余草
发布2019-08-29 11:02:25
2.1K0
发布2019-08-29 11:02:25
举报
文章被收录于专栏:业余草业余草

序列化概念

  • 序列化:把对象转化为可传输的字节序列过程称为序列化。
  • 反序列化:把字节序列还原为对象的过程称为反序列化。
640?wx_fmt=png
640?wx_fmt=png

为什么需要序列化

  • 序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是IO,而我们的IO支持的数据格式就是字节数组。
  • 因为我们单方面的只把对象转成字节数组还不行,因为没有规则的字节数组我们是没办法把对象的本来面目还原回来的,所以我们必须在把对象转成字节数组的时候就制定一种规则(序列化),那么我们从IO流里面读出数据的时候再以这种规则把对象还原回来(反序列化)。
  • 如果我们要把一栋房子从一个地方运输到另一个地方去,序列化就是我把房子拆成一个个的砖块放到车子里,然后留下一张房子原来结构的图纸,反序列化就是我们把房子运输到了目的地以后,根据图纸把一块块砖头还原成房子原来面目的过程

什么情况下需要序列化

  • 通过上面我想你已经知道了凡是需要进行“跨平台存储”和”网络传输”的数据,都需要进行序列化。
  • 本质上存储和网络传输 都需要经过 把一个对象状态保存成一种跨平台识别的字节格式,然后其他的平台才可以通过字节信息解析还原对象信息。

序列化只是一种拆装组装对象的规则,那么这种规则肯定也可能有多种多样,比如现在常见的序列化方式有:JDK(不支持跨语言)、JSON、XML、Hessian、Kryo(不支持跨语言)、Thrift、Protostuff、FST(不支持跨语言)。

Java 序列化

java 实现序列化很简单,只需要实现Serializable 接口即可。

640?wx_fmt=png
640?wx_fmt=png

注意: JAVA序列化中常见的问题

问题一:static 属性不能被序列化

原因:序列化保存的是对象的状态,静态变量属于类的状态,因此 序列化并不保存静态变量。

问题二:Transient 属性不会被序列化

java 的 transient 关键字的作用是需要实现 Serilizable 接口,将不需要序列化的属性前添加关键字 transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

问题三:序列化版本号serialVersionUID

所有实现序列化的对象都必须要有个版本号,这个版本号可以由我们自己定义,当我们没定义的时候JDK工具会按照我们对象的属性生成一个对应的版本号。使用JDK生成的 serialVersionUID,只要对象有一丁点改变serialVersionUID就会随着变更。因此建议自己手动定义该版本号。

redis序列化方式对比:

redis 的默认方式是 JdkSerializationRedisSerializer。

JdkSerializationRedisSerializer:使用JDK提供的序列化功能。优点是反序列化时不需要提供类型信息(class),但缺点是需要实现Serializable接口,还有序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。

Jackson2JsonRedisSerializer:使用Jackson库将对象序列化为JSON字符串。优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。但缺点也非常致命,那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。通过查看源代码,发现其只在反序列化过程中用到了类型信息。

问题:使用默认的JDK序列化方式,在RDM工具中查看k-v值时会出现“乱码”,不方便查看。

解决:自定义系列化方式,使用Jackson2JsonRedisSerializer

640?wx_fmt=png
640?wx_fmt=png

Redis 序列化

当你用Redis的key和value时,value对于redis来讲就是个byte array。你要自己负责把你的数据结构转换成byte array,等读取时再读出来。

一个特例是字符串,因为字符串自己几乎就已经是byte array了,所以不需要自己处理。

640?wx_fmt=png
640?wx_fmt=png

Spring 的 redisTemplate 默认会使用 java serialization 做序列化。你也可以用 StringRedisTemplate,那么你 set 的所有数据都会被 toString 一下再存到 redis 里。但这个 toString 不一定能反解析的回来。如果使用 java 原生序列化方式,可能会有远程代码执行问题,因此建议使用其他序列化方式代替。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年08月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 序列化概念
    • java 实现序列化很简单,只需要实现Serializable 接口即可。
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档