你有没有想过互联网每天要传输以EB为单位的数据(EB等于十亿GB),这么大的量级如何在表达内容相同的情况下,减少数据量级呢?Protocol Buffers就可以解决这个问题。
Protocol Buffers(简称Protobuf)是一种二进制通信协议,旨在实现结构化数据的高效、可扩展的序列化。Google开发了这种协议,以便在分布式应用程序中高效地传输和存储数据。它有以下优点:
1.性能优越:数据序列化后数据量较小、传输速度快,相比于其他格式如XML、JSON,在序列号和反序列化性能更优。
2.跨语言执行:Protobuf支持了多种语言,C++、Java、Go、Python等,便于在不同平台和编程环境下使用。
3.扩展性高:在不影响现有代码情况下,可以向协议新增字段,且不会破坏原来的代码。这有利于长期项目的发展。
4.清晰的结构:protobuf支持的数据结构基本都是日常编程中常见的。
序列化指将数据结构或者对象转化为字节流的过程,以便在网络中传输或者存在的文件系统中。
protobuf的编码是很紧凑的,我们以一个例子来讲解:
message Person {
string name = 1;
int32 age = 2;
}
上面表示的是定义为人的结构体,里面有姓名和年龄两个字段。
编码之后如下图所示,有tag和对应的值。和我们所熟悉的json不一致。
json示例,我们能清楚看到第一个字段名称是name,第二个字段名称是age。
{
"name": "B",
"age": 153
}
String编码
我们会发现protobu只有tag(序号),很难看懂,只有拿到.proto文件(也就是上面的string name=1)才能知道1表示name。
这就是为什么同样的内容数据传输会少。传输的数据为1=B,2=88,不用传递字段名称。但这种方式需要双方都有.proto文件才能解析,否则对方不知道1和2表示什么。
我们再将上述例子中的name转化为二进制。
因为name是string类型,在protobuf中序号为010表示string,所以tag表示内容为1号字段和string类型。
len表示字符串的长度,而value就是字符串的内容B。
Varint 编码
Varint是一种使用一个或多个字节序列化整数的方法,会把整数编码为变长字节。
除了不用传输字段名称,protobuf还对数字做了压缩。
我们继续将Person的age字段转成二进制。
tag内容是序列号为0的int32类型。我们需要把value转一下,因为存储的时候是小端,需要转成大端(可读性强)。
小端(Little-endian):在小端字节序中,一个多字节数据的最低有效字节(Least Significant Byte,LSB)存储在最低的内存地址,而最高有效字节(Most Significant Byte,MSB)存储在最高的内存地址。换句话说,数据的字节顺序是从低到高。
大端(Big-endian):在大端字节序中,一个多字节数据的最高有效字节(MSB)存储在最低的内存地址,而最低有效字节(LSB)存储在最高的内存地址。换句话说,数据的字节顺序是从高到低。
value中有两个字节,每个字节第一个位表示后面是否有值。剩下7个表示真正数字。上面就是10011001。
我们会发现通过每个字节第一位就能减少数据量。
以上就是Protobuf编码原理,相信看过之后你已经清楚ProtoBuf 是如何极尽所能地压榨每一寸空间和性能的。
更多学习内容,关注公粽浩:IT硅谷
本文暂时没有评论,来添加一个吧(●'◡'●)