ProtoBuf的使用和原理

一、简介

  Protobuf是一个灵活的、高效的用于序列化数据的协议。相比较XML和JSON格式,protobuf更小、更快、更便捷。Protobuf是跨语言的,并且自带了一个编译器(protoc),只需要用它进行编译,可以编译成Java、python、C++等代码,然后就可以直接使用,不需要再写其他代码,自带有解析的代码。一条消息数据,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一。
 

二、安装

1、下载代码,https://github.com/google/protobuf
2、安装protobuf
tar -xzf protobuf-2.1.0.tar.gz
cd protobuf
./configure --prefix=/usr/local/protobuf
make
make check
make install

3、配置文件

1)vim /etc/profile 和 ~/.profile 中添加:
  export PATH=$PATH:/usr/local/protobuf/bin/
  export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
2)配置动态链接库,vim /etc/ld.so.conf,在文件中添加/usr/local/protobuf/lib(注意: 在新行处添加)
3)执行:ldconfig

三、类似技术对比

1、优点

  1)Protobuf同XML相比,主要优点在于性能高。它以高效的二进制方式存储,比XML小3到10倍,快20到100倍。
  2)可以自定义数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。只需使用 Protobuf 对数据结构进行一次描述,即可利用各种不同语言或从各种不同数据流中对你的结构化数据轻松读写。
  3)“向后”兼容性好,用户不必破坏已部署的、依靠“老”数据格式的程序就可以对数据结构进行升级。这样程序就可以不必担心因为消息结构的改变而造成的大规模的代码重构或者迁移的问题。因为添加新的消息中的 field 并不会引起已经发布的程序的任何改变。
  4)Protobuf语义更清晰,无需类似XML解析器的东西。Protobuf 编译器会将.proto文件编译生成对应的数据访问类以对Protobuf数据进行序列化、反序列化操作。
  5)使用 Protobuf 无需学习复杂的文档对象模型,Protobuf 的编程模式比较友好,简单易学,同时它拥有良好的文档和示例,对于喜欢简单事物的人们而言,Protobuf 比其他的技术更加有吸引力。
 

2、不足

  1)Protbuf 与 XML 相比也有不足之处。它功能简单,无法用来表示复杂的概念。
  2)XML 已经成为多种行业标准的编写工具,Protobuf 只是 Google 公司内部使用的工具,在通用性上还差很多。
  3)由于文本并不适合用来描述数据结构,所以 Protobuf 也不适合用来对基于文本的标记文档(如 HTML)建模。
  4)由于 XML 具有某种程度上的自解释性,它可以被人直接读取编辑,在这一点上 Protobuf 不行,它以二进制的方式存储,除非你有 .proto 定义,否则你没法直接读出 Protobuf 的任何内容。
 

3、举例对比

protobuf和xml存入数据:
//在XML中建模Person的name和email字段:
<person>
<name>John Doe</name>
<email>jdoe@example.com</email>
</person> //ProtocolBuffer的文本表示:
person {
name: "John Doe"
email: "jdoe@example.com"
}

读取数据:

//操作ProtocolBuffer也很简单:
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl; //而XML的你需要:
cout << "Name: " << person.getElementsByTagName("name")->item()->innerText() << endl;
cout << "E-mail: " << person.getElementsByTagName("email")->item()->innerText() << end;

四、使用场景

  1、需要和其它系统做消息交换的,对消息大小很敏感的,那么protobuf适合了,它语言无关,消息空间相对xml和json等节省很多。
  2、小数据的场合。如果你是大数据,用它并不适合。
  3、项目语言是c++,java,python的,因为它们可以使用google的源生类库,序列化和反序列化的效率非常高。其他语言需要第三方或者自己写,序列化和反序列化的效率不保证。
 
 

五、程序示例(C++版)

     该程序示例的大致功能是,定义一个Persion结构体和存放Persion的AddressBook,然后一个写程序向一个文件写入该结构体信息,另一个程序从文件中读出该信息并打印到输出中。
1、address.proto文件
package tutorial;

message Persion {
required string name = ;
required int32 age = ;
} message AddressBook {
repeated Persion persion = ;
}
编译.proto文件,执行命令: protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto,示例中执行命令protoc --cpp_out=/tmp addressbook.proto ,会在/tmp中生成文件addressbook.pb.h和addressbook.pb.cc。
 
2、write.cpp文件,向文件中写入AddressBook信息,该文件是二进制的
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h" using namespace std; void PromptForAddress(tutorial::Persion *persion) {
cout << "Enter persion name:" << endl;
string name;
cin >> name;
persion->set_name(name); int age;
cin >> age;
persion->set_age(age);
} int main(int argc, char **argv) {
//GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != ) {
cerr << "Usage: " << argv[] << " ADDRESS_BOOL_FILE" << endl;
return -;
}
tutorial::AddressBook address_book;
{
fstream input(argv[], ios::in | ios::binary);
if (!input) {
cout << argv[] << ": File not found. Creating a new file." << endl;
}
else if (!address_book.ParseFromIstream(&input)) {
cerr << "Filed to parse address book." << endl;
return -;
}
}
// Add an address
PromptForAddress(address_book.add_persion());
{
fstream output(argv[], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
cerr << "Failed to write address book." << endl;
return -;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
//google::protobuf::ShutdownProtobufLibrary(); return ;
}
编译write.cpp文件,执行命令:g++ addressbook.pb.cc write.cpp -o write `pkg-config --cflags --libs protobuf` ,注意,这里的`符号在键盘数字1键左边,也就是和~是同一个按键。
 
3、read.cpp文件,从文件中读出AddressBook信息并打印
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h" using namespace std; void ListPeople(const tutorial::AddressBook& address_book) {
for (int i = ; i < address_book.persion_size(); i++) {
const tutorial::Persion& persion = address_book.persion(i); cout << persion.name() << " " << persion.age() << endl;
}
} int main(int argc, char **argv) {
//GOOGLE_PROTOBUF_VERIFY_VERSION; if (argc != ) {
cerr << "Usage: " << argv[] << " ADDRESS_BOOL_FILE" << endl;
return -;
} tutorial::AddressBook address_book; {
fstream input(argv[], ios::in | ios::binary);
if (!address_book.ParseFromIstream(&input)) {
cerr << "Filed to parse address book." << endl;
return -;
}
input.close();
} ListPeople(address_book); // Optional: Delete all global objects allocated by libprotobuf.
//google::protobuf::ShutdownProtobufLibrary(); return ;
}
编译read.cpp文件,g++ addressbook.pb.cc read.cpp -o read `pkg-config --cflags --libs protobuf`
 
4、执行程序结果
 
 
ref:
http://www.cnblogs.com/luoxn28/p/5303517.html
http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html#resources
 
 
 

大数据 --> ProtoBuf的使用和原理的更多相关文章

  1. 大数据系列之数据仓库Hive原理

    Hive系列博文,持续更新~~~ 大数据系列之数据仓库Hive原理 大数据系列之数据仓库Hive安装 大数据系列之数据仓库Hive中分区Partition如何使用 大数据系列之数据仓库Hive命令使用 ...

  2. 【转】五分钟读懂大数据核心MapReduce架构及原理

    什么是MapReduce Hadoop中的MapReduce是一个简单的软件框架,基于它写出的应用程序可以运行在由上千个商用机器组成的大型集群上,并以一种可靠容错式并行处理TB级数据 MapReduc ...

  3. 大数据体系概览Spark、Spark核心原理、架构原理、Spark特点

    大数据体系概览Spark.Spark核心原理.架构原理.Spark特点 大数据体系概览(Spark的地位) 什么是Spark? Spark整体架构 Spark的特点 Spark核心原理 Spark架构 ...

  4. 大数据系列之数据仓库Hive安装

    Hive系列博文,持续更新~~~ 大数据系列之数据仓库Hive原理 大数据系列之数据仓库Hive安装 大数据系列之数据仓库Hive中分区Partition如何使用 大数据系列之数据仓库Hive命令使用 ...

  5. 大数据系列之数据仓库Hive命令使用及JDBC连接

    Hive系列博文,持续更新~~~ 大数据系列之数据仓库Hive原理 大数据系列之数据仓库Hive安装 大数据系列之数据仓库Hive中分区Partition如何使用 大数据系列之数据仓库Hive命令使用 ...

  6. 大数据系列之数据仓库Hive中分区Partition如何使用

    Hive系列博文,持续更新~~~ 大数据系列之数据仓库Hive原理 大数据系列之数据仓库Hive安装 大数据系列之数据仓库Hive中分区Partition如何使用 大数据系列之数据仓库Hive命令使用 ...

  7. 大数据运算模型 MapReduce 原理

    大数据运算模型 MapReduce 原理 2016-01-24 杜亦舒 MapReduce 是一个大数据集合的并行运算模型,由google提出,现在流行的hadoop中也使用了MapReduce作为计 ...

  8. 大数据组件原理总结-Hadoop、Hbase、Kafka、Zookeeper、Spark

    Hadoop原理 分为HDFS与Yarn两个部分.HDFS有Namenode和Datanode两个部分.每个节点占用一个电脑.Datanode定时向Namenode发送心跳包,心跳包中包含Datano ...

  9. Atitit. BigConfirmTips 控件 大数据量提示确认控件的原理and总结O9

    Atitit. BigConfirmTips 控件 大数据量提示确认控件的原理and总结O9 1. 主要的涉及的技术 1 2. 主要的流程 1 3. 调用法new confirmO9t(); 1 4. ...

随机推荐

  1. mongodb去除重复的数据

    里边的内容在某些情况下不可行,可以参考下一篇. 今天出现了一个新的需求,有个部门需要拿到mongodb中的数据,要求去掉其中一个字段内容相同的数据. 虽然mongodb中有distinct来去重,但是 ...

  2. R语言︱数据规范化、归一化

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:规范化主要是因为数据受着单位的影响较 ...

  3. WebService之CXF注解之五(配置文件)

    1.web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=" ...

  4. org.apache.jasper.JasperException: /pages/path.jsp

    1.错误描述 三月 15, 2015 8:56:37 下午 org.apache.jasper.compiler.TldLocationsCache tldScanJar 信息: At least o ...

  5. 芝麻HTTP:爬虫的基本原理

    我们可以把互联网比作一张大网,而爬虫(即网络爬虫)便是在网上爬行的蜘蛛.把网的节点比作一个个网页,爬虫爬到这就相当于访问了该页面,获取了其信息.可以把节点间的连线比作网页与网页之间的链接关系,这样蜘蛛 ...

  6. java 堆 栈 常量池

    java 堆中保存new 出来的对象(每个对象都包含一个与之对应的class的信息,[class信息存放在方法区]),堆中分配的内存,有虚拟机的自动垃圾回收器管理,栈内存只对其所属线程可见. java ...

  7. .Net之路,感谢对我深远影响的三位前辈

    为什么要写这篇文章?为什么创立这个站点? 本人大四,学习.Net三年有余,随着近期开始转向对.Net Core的关注,我开始了解到了张善友(www.csharpkit.com).腾飞(www.jess ...

  8. ubuntu14.04安装cuda

    1 装系统时候注意,另外14.04要好于12.04,自带了无线驱动 ubuntu14.04安装完不要update 2 安装cuda和cudnn http://blog.csdn.net/l297969 ...

  9. PortableApps使用入门

    PortableApps使用入门 Software 介绍 添加软件 绿软下载站推荐 介绍 官网:http://portableapps.com/ PortableApps作为一款卓越的绿软管理软件,它 ...

  10. 自定义WIZ文档模板

    WIZ文档模板 1.在wiz笔记里面新建一个笔记,并将其做成一个模板 例子: 2.该作为模板的笔记制作完成后,右键-高级-另存为  导出为html格式 3.将导出的文件和文件夹(有时候只有一个htm文 ...