Protocol Buffers(通常简称 Protobuf)是由 Google 开发的一种数据序列化协议。它提供了一种高效、平台无关、可扩展的序列化结构化数据的方式,广泛用于各种应用场景,如数据存储、RPC(远程过程调用)和消息传递系统。
核心概念
数据结构
- Protobuf 使用 .proto 文件来定义数据结构。这些文件定义了消息的格式和字段,包括字段的名称、类型和编号。字段编号在序列化和反序列化过程中用于标识数据。
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
}
message AddressBook {
repeated Person people = 1;
}
- syntax = “proto3”; 指定了使用 Protobuf 的版本。
- message 关键字定义了一个消息类型(即数据结构)。
- string name = 1; 定义了一个字段,其中 string 是字段的类型,name 是字段名,1 是字段编号。
编译 .proto 文件
- 使用 Protobuf 编译器 protoc 将 .proto 文件编译为特定编程语言的源代码。编译器生成的代码提供了用于序列化和反序列化数据的类或结构体。
protoc --python_out=. addressbook.proto # 将 addressbook.proto 编译为 Python 源代码,并将生成的文件存储在当前目录下。
序列化和反序列化
- 创建对象
import addressbook_pb2
# 创建一个 Person 对象
person = addressbook_pb2.Person()
person.name = 'Alice'
person.id = 123
person.email = 'alice@example.com'
- 序列化
# 将 Person 对象序列化为字节流
serialized_person = person.SerializeToString()
- 反序列化
# 从字节流反序列化为 Person 对象
new_person = addressbook_pb2.Person()
new_person.ParseFromString(serialized_person)
print(new_person)
Protobuf 优点
- 高效:Protobuf 的二进制格式非常紧凑,相比 JSON 和 XML 占用更少的存储空间和带宽。同时,它的序列化和反序列化速度也更快。
- 跨语言支持:Protobuf 支持多种编程语言,包括 C++、Java、Python、Go、C#、JavaScript 等。这使得它能够在不同的语言和平台之间进行数据交换。
- 向后兼容性:Protobuf 允许在不破坏现有数据的情况下对数据结构进行演化。例如,可以添加新字段而不影响旧版本的数据解析。
- 自定义选项:Protobuf 允许定义自定义选项和扩展,使其可以满足各种应用的需求。
Protobuf 的应用
- 网络通信:Protobuf 被广泛用于分布式系统中的消息传递和远程过程调用(RPC)。它的高效性和平台无关性使其成为 RPC 框架(如 gRPC)的首选序列化协议。
- 数据存储:Protobuf 用于存储和持久化数据,特别是在需要高效存储和快速访问的场景中,例如数据库存储和文件存储。
- 配置文件:Protobuf 可用于存储和解析结构化配置文件,为复杂的配置提供了一种结构化的方式。