你真的理解序列化和反序列化吗?

背景

  • 序列化协议有哪些,这些在序列化协议有什么区别?redission的写入的时候采用的是什么序列化协议?在使用RPC调用的时候,他的序列化是如何实现的?
  • 灵魂拷问,感觉自己是个渣渣!

序列化和反序列化的概念

  • 互联网的产生带来了机器间通讯的需求,而互联通讯的双方需要采用约定的协议,序列化和反序列化属于通讯协议的一部分。通讯协议往往采用分层模型,不同模型每层的功能定义以及颗粒度不同,例如:TCP/IP协议是一个四层协议,而OSI模型却是七层协议模型。在OSI七层协议模型中展现层(Presentation Layer)的主要功能是把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象–这两个功能就是序列化和反序列化。
  • 序列化: 将数据结构或对象转换成二进制串的过程
  • 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程。
  • 通过上面可知,从本机应用程序到其他服务器应用程序的服务调用过程,数据的传输则需要进行序列化后传输。将我们的特殊数据结果经过序列化变为二进制文件,然后通过反序列化得到对应的对象或数据信息。

序列化和反序列化的组件

  • IDL(Interface description language)文件:参与通讯的各方需要对通讯的内容需要做相关的约定(Specifications)。为了建立一个与语言和平台无关的约定,这个约定需要采用与具体开发语言、平台无关的语言来进行描述。这种语言被称为接口描述语言(IDL),采用IDL撰写的协议约定称之为IDL文件。通俗的讲这也就是一个约定序列化的一种方式
  • IDL Compiler:IDL文件中约定的内容为了在各语言和平台可见,需要有一个编译器,将IDL文件转换成各语言对应的动态库。
  • Stub/Skeleton Lib:负责序列化和反序列化的工作代码。Stub是一段部署在分布式系统客户端的代码,一方面接收应用层的参数,并对其序列化后通过底层协议栈发送到服务端,另一方面接收服务端序列化后的结果数据,反序列化后交给客户端应用层;Skeleton部署在服务端,其功能与Stub相反,从传输层接收序列化参数,反序列化后交给服务端应用层,并将应用层的执行结果序列化后最终传送给客户端Stub。
  • Client/Server:指的是应用层程序代码,他们面对的是IDL所生存的特定语言的class或struct。
  • 底层协议栈和互联网:序列化之后的数据通过底层的传输层、网络层、链路层以及物理层协议转换成数字信号在互联网中传递

在这里插入图片描述

  1. 通过图我们可知,在进行网络传输的过程中我们需要将应用程序中的数据对象,转换为可传输的二进制字节流的步骤是通过IDL file所描述的规则通过 IDL 编译器编译为对应应用程序的序列化规则。对应的应用程序通过stub/Skeleton 进行序列化和反序列化。且将应用层的数据通过底层协议栈进行发送。这也就是大概的一个序列化过程。
  • 我突然有一个疑问那java中的Seralizable和 Stub/skeleton的关系是什么呢?
  1. 个人理解就是Serializable就是将对象持久化存储的时候需要给类打上这个标签。
  2. Seralizable是针对于持久化存储,而Stub/skeleton针对的是网络传输。(个人见解)

常用的序列化协议

XML

  • 是一种常用的序列化和反序列化协议,具有跨机器,跨语言等优点。 XML历史悠久,其1.0版本早在1998年就形成标准,并被广泛使用至今。XML的最初产生目标是对互联网文档(Document)进行标记,所以它的设计理念中就包含了对于人和机器都具备可读性。 但是,当这种标记文档的设计被用来序列化对象的时候,就显得冗长而复杂(Verbose and Complex)。 XML本质上是一种描述语言,并且具有自我描述(Self-describing)的属性,所以XML自身就被用于XML序列化的IDL。 标准的XML描述格式有两种:DTD(Document Type Definition)和XSD(XML Schema Definition)。作为一种人眼可读(Human-readable)的描述语言,XML被广泛使用在配置文件中,例如O/R mapping、 Spring Bean Configuration File 等。

SOAP

  • SOAP(Simple Object Access protocol)是一种被广泛应用的,基于XML为序列化和反序列化协议的结构化消息传递协议。SOAP在互联网影响如此大,以至于我们给基于SOAP的解决方案一个特定的名称–Web service。SOAP虽然可以支持多种传输层协议,不过SOAP最常见的使用方式还是XML+HTTP。SOAP协议的主要接口描述语言(IDL)是WSDL(Web Service Description Language)。SOAP具有安全、可扩展、跨语言、跨平台并支持多种传输层协议。如果不考虑跨平台和跨语言的需求,XML的在某些语言里面具有非常简单易用的序列化使用方法,无需IDL文件和第三方编译器, 例如Java+XStream。

JSON(Javascript Object Notation)

  • JSON起源于弱类型语言Javascript, 它的产生来自于一种称之为”Associative array”的概念,其本质是就是采用”Attribute-value”的方式来描述对象。实际上在Javascript和PHP等弱类型语言中,类的描述方式就是Associative array。JSON的如下优点,使得它快速成为最广泛使用的序列化协议之一:JSON起源于弱类型语言Javascript, 它的产生来自于一种称之为”Associative array”的概念,其本质是就是采用”Attribute-value”的方式来描述对象。实际上在Javascript和PHP等弱类型语言中,类的描述方式就是Associative array。
  • JSON的如下优点,使得它快速成为最广泛使用的序列化协议之一:
  1. 这种Associative array格式非常符合工程师对对象的理解。
  2. 它保持了XML的人眼可读(Human-readable)的优点。
  3. 相对于XML而言,序列化后的数据更加简洁。 来自于的以下链接的研究表明:XML所产生序列化之后文件的大小接近JSON的两倍。http://www.codeproject.com/Articles/604720/JSON-vs-XML-Some-hard-numbers-about-verbosity 。
  4. 它具备Javascript的先天性支持,所以被广泛应用于Web browser的应用常景中,是Ajax的事实标准协议。
  5. 与XML相比,其协议比较简单,解析速度比较快。
  6. 松散的Associative array使得其具有良好的可扩展性和兼容性。

Thrift

Thrift是Facebook开源提供的一个高性能,轻量级RPC服务框架,其产生正是为了满足当前大数据量、分布式、跨语言、跨平台数据通讯的需求。 但是,Thrift并不仅仅是序列化协议,而是一个RPC框架。相对于JSON和XML而言,Thrift在空间开销和解析性能上有了比较大的提升,对于对性能要求比较高的分布式系统,它是一个优秀的RPC解决方案;但是由于Thrift的序列化被嵌入到Thrift框架里面,Thrift框架本身并没有透出序列化和反序列化接口,这导致其很难和其他传输层协议共同使用(例如HTTP)。

Protobuf

Protobuf具备了优秀的序列化协议的所需的众多典型特征:

1、标准的IDL和IDL编译器,这使得其对工程师非常友好。

2、序列化数据非常简洁,紧凑,与XML相比,其序列化之后的数据量约为1/3到1/10。

3、解析速度非常快,比对应的XML快约20-100倍。

4、提供了非常友好的动态库,使用非常简介,反序列化只需要一行代码。

Protobuf是一个纯粹的展示层协议,可以和各种传输层协议一起使用;Protobuf的文档也非常完善。 但是由于Protobuf产生于Google,所以目前其仅仅支持Java、C++、Python三种语言。另外Protobuf支持的数据类型相对较少,不支持常量类型。由于其设计的理念是纯粹的展现层协议(Presentation Layer),目前并没有一个专门支持Protobuf的RPC框架

Avro

  • Avro的产生解决了JSON的冗长和没有IDL的问题,Avro属于Apache Hadoop的一个子项目。 Avro提供两种序列化格式:JSON格式或者Binary格式。Binary格式在空间开销和解析性能方面可以和Protobuf媲美,JSON格式方便测试阶段的调试。 Avro支持的数据类型非常丰富,包括C++语言里面的union类型。Avro支持JSON格式的IDL和类似于Thrift和Protobuf的IDL(实验阶段),这两者之间可以互转。Schema可以在传输数据的同时发送,加上JSON的自我描述属性,这使得Avro非常适合动态类型语言。 Avro在做文件持久化的时候,一般会和Schema一起存储,所以Avro序列化文件自身具有自我描述属性,所以非常适合于做Hive、Pig和MapReduce的持久化数据格式。对于不同版本的Schema,在进行RPC调用的时候,服务端和客户端可以在握手阶段对Schema进行互相确认,大大提高了最终的数据解析速度

总结

  1. 序列化的含义是:在网络传输的时候可以将应用层的数据结构或对象转化为对应的序列化协议的格式。
  2. 网络传输序列化的过程:序列化协议的定义是存储在IDL文件中,通过IDL complier 可以解析,然后通过Stub/Skeleton进行转换为对应的引用程序的数据类型。如JSOn 格式的化 就可以转换为Java的对象格式等。
  3. 本地持久化序列化的过程:使用Serilizable接口为java的类打标签,进行序列化持久化到本地。
  4. 在网络传输时经常使用的集中序列化协议,其中Json是我们平时比较常使用的。因为相对于其他的序列化协议,他是易理解,兼容性好,传输的内容大小也小。
  5. redisson的序列化协议:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pg2NFyF3-1595257744653)(http://note.youdao.com/yws/res/16571/C8654E69FDB24CB19CBD908FD74434F9)]

参考

  • https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html(美团技术团队)
  • https://blog.csdn.net/weixin_33756418/article/details/89781241
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值