目录
整理思考序列化与反序列化的一些知识点及具体的选型
序列化和反序列化是通讯协议的一部分,恰当的序列化协议可以提高系统的通用性、强健性、安全性、优化系统性能,而且让系统可以更加易于调试、便于扩展。
本质上,序列化就是将数据结构或对象转换成二进制串的过程,反序列化则是将序列化过程中所生成的二进制串转换成数据结构。这里关于二进制串尤其要注意就是C++是可以直接操作内存,其字符串本质就是\0结尾存储在内存中的二进制串。而Java是面向对象String是一个对象,对应的二进制串是byte[],byte是原生数据类型之一
特性
通用性
技术层面,序列化是否支持跨平台、跨语言。
流行程度,流行程度代表着学习成本,和是否有稳定而成熟的跨语言、跨平台的公共包。
强健性/鲁棒性
成熟度,其是否经过全面大量的测试
语言平台公平性,放弃某语言特性,或者因为平台放弃协议的特性
可调试性/可读性
人眼可读将会提高调试效率如xml或者json
性能
空间开销(Verbosity),序列化增加描述字段,是否会带来过大的开销
时间开销(Complexity),复杂的序列化协议会导致较长的解析时间,会使得此成为系统的瓶颈。
可扩展性/兼容性
是否有良好的可扩展性,支持自动增加新的业务字段,而不影响老的服务
安全性/访问限制
访问限制而降低服务可用性
被迫重新实现安全协议而导致实施成本提高
开放更多的防火墙端口和协议访问,牺牲安全性
序列化和反序列化组件
IDL
参与通讯的各方需要对通讯的内容需要做相关的约定(Specifications)
IDL Compiler
为了各语言和平台课件,需要编译器,将IDL文件转换成个语言对应的动态库。
Stub/Skeleton lib
负责序列化和反序列化工作代码
Client/Server
应用层程序代码,面对的是IDL所生存的特定语言的class或struct
底层协议栈和互联网
通过底层的传输层网络层链路层以及物理层协议转换成数字信号在互联网中传递
几种常见的协议
COM
主要用于windows平台 利用了编译器徐彪 学习成本巨大
CORBA
跨平台 跨语言 但是版本较多 Java1.3后支持
XML&SOAP
SOAP(Simple Object Access protocol) 是一种被广泛应用的,基于XML为序列化和反序列化协议的结构化消息传递协议。XML优点,人眼可读,缺点,额外空间开销大,时间空间开销都大,对性能要求在ms级别服务不推荐用,
JSON
起源于JavaScript,实时性不高,一般的ajax请求接口类较常用,典型场景是JSON+HTTP,缺少IDL只能文档约束,由于JSON在一些语言中的序列化和反序列化需要采用反射机制,所以在性能要求为ms级别,不建议使用。
Thrift
Facebook产品,高性能轻量级RPC框架,满足大数据量分布式跨语言跨平台数据通讯的需求,相对json与xml性能要高,同时其是框架一部分,所以不能与其他协议公用。较适合公司内部,基于自身socket服务,跨防火墙访问时,安全是一个顾虑,公司间通讯时需要谨慎。序列化后的数据是Binary数组,不具有可读性。另其无法支持向持久层直接读写数据,所以不适合做数据持久化序列化协议。
Protobuf
Google产品 支持Java C++ Python,支持数据类型较少不支持敞亮。目前没有专门支持其的RPC框架。解析速度是xml20-100倍,简洁度是xml的1/3到1/10。
Avro
Apache Hadoop子项目,提供两种序列化格式:JSON格式或者Binary格式。支持数据类型丰富。Avro在做文件持久化的时候,一般会和Schema一起存储,所以Avro序列化文件自身具有自我描述属性,所以非常适合于做Hive、Pig和MapReduce的持久化数据格式。
解析性能
空间开销
从上图可得出如下结论:
1、XML序列化(Xstream)无论在性能和简洁性上比较差。
2、Thrift与Protobuf相比在时空开销方面都有一定的劣势。
3、Protobuf和Avro在两方面表现都非常优越。
总结
以上描述的五种序列化和反序列化协议都各自具有相应的特点,适用于不同的场景:
1、对于公司间的系统调用,如果性能要求在100ms以上的服务,基于XML的SOAP协议是一个值得考虑的方案。
2、基于Web browser的Ajax,以及Mobile app与服务端之间的通讯,JSON协议是首选。对于性能要求不太高,或者以动态类型语言为主,或者传输数据载荷很小的的运用场景,JSON也是非常不错的选择。
3、对于调试环境比较恶劣的场景,采用JSON或XML能够极大的提高调试效率,降低系统开发成本。
4、当对性能和简洁性有极高要求的场景,Protobuf,Thrift,Avro之间具有一定的竞争关系。
5、对于T级别的数据的持久化应用场景,Protobuf和Avro是首要选择。如果持久化后的数据存储在Hadoop子项目里,Avro会是更好的选择。
6、由于Avro的设计理念偏向于动态类型语言,对于动态语言为主的应用场景,Avro是更好的选择。
7、对于持久层非Hadoop项目,以静态类型语言为主的应用场景,Protobuf会更符合静态类型语言工程师的开发习惯。
8、如果需要提供一个完整的RPC解决方案,Thrift是一个好的选择。
9、如果序列化之后需要支持不同的传输层协议,或者需要跨防火墙访问的高性能场景,Protobuf可以优先考虑。
感谢!文章参考整理:序列化与反序列化