大資料 --> ProtoBuf的使用和原理

來源:互聯網
上載者:User

標籤:

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/protobufmakemake checkmake 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)Protobuf同XML相比,主要優點在於效能高。它以高效的二進位方式儲存,比XML小3到10倍,快20到100倍。  2)可以自訂資料結構,然後使用代碼產生器產生的程式碼來讀寫這個資料結構。你甚至可以在無需重新部署程式的情況下更新資料結構。只需使用 Protobuf 對資料結構進行一次描述,即可利用各種不同語言或從各種不同資料流中對你的結構化資料輕鬆讀寫。  3)“向後”相容性好,使用者不必破壞已部署的、依靠“老”資料格式的程式就可以對資料結構進行升級。這樣程式就可以不必擔心因為訊息結構的改變而造成的大規模的代碼重構或者遷移的問題。因為添加新的訊息中的 field 並不會引起已經發布的程式的任何改變。  4)Protobuf語義更清晰,無需類似XML解析器的東西。Protobuf 編譯器會將.proto檔案編譯產生對應的資料訪問類以對Protobuf資料進行序列化、還原序列化操作。  5)使用 Protobuf 無需學習複雜的文件物件模型,Protobuf 的編程模式比較友好,簡單易學,同時它擁有良好的文檔和樣本,對於喜歡簡單事物的人們而言,Protobuf 比其他的技術更加有吸引力。  不足:  1)Protbuf 與 XML 相比也有不足之處。它功能簡單,無法用來表示複雜的概念。  2)XML 已經成為多種行業標準的編寫工具,Protobuf 只是 Google 公司內部使用的工具,在通用性上還差很多。  3)由於文本並不適合用來描述資料結構,所以 Protobuf 也不適合用來對基於文本的標記文檔(如 HTML)建模。  4)由於 XML 具有某種程度上的自解釋性,它可以被人直接讀取編輯,在這一點上 Protobuf 不行,它以二進位的方式儲存,除非你有 .proto 定義,否則你沒法直接讀出 Protobuf 的任何內容。  舉例對比protobuf和xml存入資料:
//在XML中建模Person的name和email欄位:<person>    <name>John Doe</name>    <email>[email protected]</email></person>//ProtocolBuffer的文本表示:person {    name: "John Doe"    email: "[email protected]"}

讀取資料:

//操作ProtocolBuffer也很簡單:cout << "Name: " << person.name() << endl;cout << "E-mail: " << person.email() << endl;//而XML的你需要:cout << "Name: " << person.getElementsByTagName("name")->item(0)->innerText() << endl;cout << "E-mail: " << person.getElementsByTagName("email")->item(0)->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 = 1;    required int32 age = 2;}message AddressBook {    repeated Persion persion = 1;}
編譯.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 != 2) {        cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;        return -1;    }    tutorial::AddressBook address_book;    {        fstream input(argv[1], ios::in | ios::binary);        if (!input) {            cout << argv[1] << ": File not found. Creating a new file." << endl;        }        else if (!address_book.ParseFromIstream(&input)) {            cerr << "Filed to parse address book." << endl;            return -1;        }    }    // Add an address    PromptForAddress(address_book.add_persion());    {        fstream output(argv[1], ios::out | ios::trunc | ios::binary);        if (!address_book.SerializeToOstream(&output)) {            cerr << "Failed to write address book." << endl;            return -1;        }    }    // Optional: Delete all global objects allocated by libprotobuf.    //google::protobuf::ShutdownProtobufLibrary();    return 0;}
編譯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 = 0; 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 != 2) {        cerr << "Usage: " << argv[0] << " ADDRESS_BOOL_FILE" << endl;        return -1;    }    tutorial::AddressBook address_book;    {        fstream input(argv[1], ios::in | ios::binary);        if (!address_book.ParseFromIstream(&input)) {            cerr << "Filed to parse address book." << endl;            return -1;        }        input.close();    }    ListPeople(address_book);    // Optional: Delete all global objects allocated by libprotobuf.    //google::protobuf::ShutdownProtobufLibrary();    return 0;}
編譯read.cpp檔案,g++ addressbook.pb.cc read.cpp -o read `pkg-config --cflags --libs protobuf` 4、執行程式結果  ref:http://www.cnblogs.com/luoxn28/p/5303517.htmlhttp://www.ibm.com/developerworks/cn/linux/l-cn-gpb/index.html#resources   

大資料 --> ProtoBuf的使用和原理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.