一、三大主流开源持久化框架介绍
1.1 Google Protocol Buffer
protocol buffer是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输,配置文件,数据存储等诸多领域。
1.2 Apache Thrift
thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
thrift允许定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
1.3 Apache avro
Avro是一个数据序列化的系统,它可以提供丰富的数据结构类型,快速可压缩的二进制数据形式,存储持久数据的文件容器,远程过程调用RPC。
Avro依赖于模式(Schema)。Avro数据的读写操作是很频繁的,而这些操作都需要使用模式,这样就减少写入每个数据资料的开销,使得序列化快速而又轻巧。这种数据及其模式的自我描述方便于动态脚本语言的使用。当Avro数据存储到文件中时,它的模式也随之存储,这样任何程序都可以对文件进行处理。如果需要以不同的模式读取数据,这也很容易解决,因为两个模式都是已知的。Avro模式是用JSON定义的,这样对于已经拥有JSON库的语言可以容易实现。
1.4 三大持久化框架对比分析
二、Google Protocol Buffer使用指导
这部分主要参考Google官方指导文档,链接地址https://developers.google.com/protocol-buffers/docs/proto。Google Protocol Buffer目前指导C/C++、Java和Python三种开发语言。
2.1 Protocol Buffer开发过程
2.2定义.proto文件
2.2.1定义一个消息类型
这里以一个消息为例来进行说明。
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3 [default = 10];
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
optional Corpus corpus = 4 [default = UNIVERSAL];
}
2.2.2支持的修饰关键字
required:持久化流中必须出现
options:持久化流中可以不出现或者最多出现一次。可以设置默认值。
repeated:持久化流中可以出现0次或者多次。对于整数可以设置压缩。
2.2.3支持的对象类型
message:定义消息
enum:定义枚举
2.2.4支持的值类型
这里主要说明.proto文件中使用的类型和编译后生成的开发语言类型的对应关系。
.proto Type | Notes | C++ Type | Java Type |
double | double | double | |
float | float | float | |
int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int |
int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long |
uint32 | Uses variable-length encoding. | uint32 | int[1] |
uint64 | Uses variable-length encoding. | uint64 | long[1] |
sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int |
sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long |
fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 228. | uint32 | int[1] |
fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 256. | uint64 | long[1] |
sfixed32 | Always four bytes. | int32 | int |
sfixed64 | Always eight bytes. | int64 | long |
bool | bool | boolean | |
string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String |
bytes | May contain any arbitrary sequence of bytes. | string | ByteString |
2.2.5支持的选项
java_package:指定编译后生成的java包名
java_outer_classname:指定编译后生成的java类名
optimize_for:指定编译采用的方式。SPEED表示持久化效率优化;CODE_SIZE表示生成的类最小;LITE_RUNTIME生成最小化的类,适合用于嵌入式环境。
2.3编译.proto文件生成类
2.3.1使用protoc工具进行编译
使用protocol编译器进行编译。
protoc --proto_path=