google protocol buffer 與 redis 結合使用

來源:互聯網
上載者:User

google protocol buffer 可以將對象序列化,而redis作為優秀的NOSQL資料庫,這裡我將以執行個體方式介紹,將C++對象序列化,並存放在redis資料庫中!

 

google protocol buffer 的安裝以及基礎使用可以閱讀我上一片文章.

redis的安裝使用,可以查閱,這裡不再描述.我使用redis的官方C client: hiredis.

 

protobuf 物件模型:

package cn.vicky.model.seri;message User {    required int32 id = 1; // 主鍵,唯一    required string username = 2; // 帳號    required string password = 3; // 密碼    optional string email = 4; // 郵箱(可選)    repeated Person person = 5; // 賬戶擁有的角色(可以重複)}message Person {     required int32 id = 1; // 主鍵,唯一    required string name = 2; // 角色名稱字    repeated PhoneNumber phone = 3; // 電話號碼(可以重複)} // 枚舉類型enum PhoneType {     MOBILE = 0;     HOME = 1;     WORK = 2; } message PhoneNumber {     required string number = 1;     optional PhoneType type = 2 [default = HOME]; } 

 

建立工程:

在產生對應的model.pb.h  model.pb.cc 更多請閱讀我上一篇文章.

將hiredis.h以及依賴庫引入項目中.這裡以靜態連結庫形式  /usr/lib/libhiredis.a

編寫main,cpp

/*  * File:   main.cpp * Author: Vicky.H * Email:  eclipser@163.com */#include <iostream>#include <fstream>#include "model.pb.h"#include "hiredis.h"/* *  */int main(void) {    // 建立User對象    cn::vicky::model::seri::User u;    u.set_id(1);    u.set_username("Jack");    u.set_password("123456");    u.set_email("289997171@qq.com");    // 建立User中的一個角色    cn::vicky::model::seri::Person* _person1 = u.add_person();    _person1->set_id(1);    _person1->set_name("P1");    // 建立角色中的一個電話號碼:1    cn::vicky::model::seri::PhoneNumber* _phone1 = _person1->add_phone();    _phone1->set_number("+8613618074943");    _phone1->set_type(cn::vicky::model::seri::MOBILE);    // 建立角色中的一個電話號碼:2    cn::vicky::model::seri::PhoneNumber* _phone2 = _person1->add_phone();    _phone2->set_number("02882334717");    _phone2->set_type(cn::vicky::model::seri::WORK);    // 建立User中的一個角色    cn::vicky::model::seri::Person* _person2 = u.add_person();    _person2->set_id(2);    _person2->set_name("P2");    // 建立角色中的一個電話號碼:1    cn::vicky::model::seri::PhoneNumber* _phone3 = _person2->add_phone();    _phone3->set_number("+8613996398667");    _phone3->set_type(cn::vicky::model::seri::MOBILE);    // 建立角色中的一個電話號碼:2    cn::vicky::model::seri::PhoneNumber* _phone4 = _person2->add_phone();    _phone4->set_number("02882334717");    _phone4->set_type(cn::vicky::model::seri::WORK);    // 將對象以二進位儲存    const int byteSize = u.ByteSize();    std::cout << "byteSize = " << byteSize << std::endl;    char buf[byteSize];    bzero(buf, byteSize);    u.SerializeToArray(buf, byteSize);    // 建立redis連結    redisContext *c;    redisReply *reply;    struct timeval timeout = {1, 500000}; // 1.5 seconds    c = redisConnectWithTimeout((char*) "127.0.0.1", 3307, timeout);    if (c->err) {        printf("Connection error: %s\n", c->errstr);        exit(1);    }//    第一次執行:將對象寫入redis資料庫//    reply = (redisReply*) redisCommand(c, "SET %b %b", u.username().c_str(), (int) u.username().length(), buf, byteSize); // 重點!!!//    printf("SET (binary API): %s\n", reply->str);//    freeReplyObject(reply);//    第二次執行:從redis資料庫讀取對象資料    reply = (redisReply*) redisCommand(c, "Get Jack");    std::cout << "reply->len = " << reply->len << "\nreply->str : \n" << reply->str << std::endl; // 這裡列印不完    std::cout << "---------------------------" << std::endl;    cn::vicky::model::seri::User u2;    u2.ParseFromArray(reply->str, reply->len);    std::cout << u2.id() << std::endl;    std::cout << u2.username() << std::endl;    std::cout << u2.password() << std::endl;    std::cout << u2.email() << std::endl;    std::cout << "---------------------------" << std::endl;    for (int i = 0; i < u2.person_size(); i++) {        cn::vicky::model::seri::Person* p = u2.mutable_person(i);        std::cout << p->id() << std::endl;        std::cout << p->name() << std::endl;        for (int j = 0; j < p->phone_size(); j++) {            cn::vicky::model::seri::PhoneNumber* phone = p->mutable_phone(j);            std::cout << phone->number() << std::endl;        }        std::cout << "---------------------------" << std::endl;    }    return 0;}

 

首先:

[root@localhost ~]# redis-cli -p 3307
redis 127.0.0.1:3307> DEL Jack
(integer) 1
redis 127.0.0.1:3307>

運行第一個注釋,將對象寫入redis:

byteSize = 124
SET (binary API): OK
0

這裡已經成功將User u的對象寫入到redis中了,我們可以通過redis查看:

redis 127.0.0.1:3307> GET Jack
"\b\x01\x12\x04Jack\x1a\x06123456\"\x10289997171@qq.com*+\b\x01\x12\x02P1\x1a\x12\n\x0e+8613618074943\x10\x00\x1a\x0f\n\x0b02882334717\x10\x02*+\b\x02\x12\x02P2\x1a\x12\n\x0e+8613996398667\x10\x00\x1a\x0f\n\x0b02882334717\x10\x02"

 

運行第二個注釋,從redis中讀取Jack資料,並還原序列化產生User u2;

結果:

byteSize = 124
reply->len = 124
reply->str :
Jack123456"289997171@qq.com*P1           直接列印位元據是不正確的!!!
+8613618074943
---------------------------
1
Jack
123456
289997171@qq.com
---------------------------
1
P1
+8613618074943
02882334717
---------------------------
2
P2
+8613996398667
02882334717
---------------------------

 

Great...那麼,protobuf 與 redis的結合成功了!

個人認為,這種物件導向,並且跨語言,在儲存和讀取依賴redis記憶體資料庫的基礎上是非常的高效能!

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.