菜鸟笔记
提升您的技术认知

Protobuf原理

一、Protobuf是什么?

Protobuf就是一个网络通信协议,它提供了高效率的序列化与反序列化机制,

网络通讯协议:在计算机网络中进行数据交换而建立的规则、标准或约定的集合。

序列化:

序列化是将数据结构或对象转换成二进制字节流的过程。

Protobuf对于不同的字段类型采用不同的编码方式和数据存储方式对消息字段进行序列化,以确保得到高效紧凑的数据压缩。

Protobuf序列化过程如下:

1)判断每个字段是否有设置值,有值才进行编码。

2)根据字段标识号与数据类型将字段值通过不同的编码方式进行编码。

3)将编码后的数据块按照字段类型采用不同的数据存储方式封装成二进制数据流。

反序列化:

反序列化是将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程。

Protobuf反序列化过程如下:

1)调用消息类的parseFrom(input)解析从输入流读入的二进制字节数据流。

2)将解析出来的数据按照指定的格式读取到Java、C++、Phyton对应的结构类型中。

二、protobuf序列化原理是什么?

1.Protobuf数据存储三大原则:

1)Protocol Buffer将消息中的每个字段进行编码后,利用T - L - V 存储方式进行数据的存储,最终得到一个二进制字节流。

2)ProtoBuf对于不同数据类型采用不同的序列化方式(数据编码方式与数据存储方式)

Protobuf对于不同的字段类型采用不同的编码和数据存储方式对消息字段进行序列化,以确保得到高效紧凑的数据压缩。不同类型的数据采用的编码方式和存储方式如下:

对于Varint编码数据的存储,不需要存储字节长度Length,使用T-V存储方式进行存储;对于采用其它编码方式(如LENGTH_DELIMITED)的数据,使用T-L-V存储方式进行存储。

3)ProtoBuf对于数据字段值的独特编码方式与T-L-V数据存储方式,使得 ProtoBuf序列化后数据量体积极小。

2、WireType=0的序列化

WireType=0的类型包括int32,int64,uint32,unint64,bool,enum以及sint32和sint64。

编码方式采用Varint编码(如果为负数,采用Zigzag辅助编码),数据存储方式使用T-V方式存储二进制字节流。

3、WireType=1的序列化

WireType=1的类型包括fixed64,sfixed64,double。

编码方式采用64bit编码(编码后数据大小为64bit,高位在后,低位在前),数据存储方式使用T-V方式存储二进制字节流。

4、WireType=2的序列化

WireType=2的类型包括string,bytes,嵌套消息,packed repeated字段。

对于编码方式,标识符Tag采用Varint编码,字节长度Length采用Varint编码,string类型字段值采用UTF-8编码,嵌套消息类型的字段值根据嵌套消息内部的字段数据类型进行选择,

数据存储方式使用T-L-V方式存储二进制字节流。