ItGo.me - 专注IT技术分享

首页 > Redis > google protocol buffer 与 redis 结合使用

google protocol buffer 与 redis 结合使用

时间:2016-08-28来源:网友分享 点击:

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  更多请阅读我上一篇文章.

将hiredis.h以及依赖库引入项目中.这里以静态链接库形式  /usr/lib/libhiredis.a

编写main,cpp

/** File:   main.cpp* Author: Vicky.H* Email:  eclipser@*/#include <iostream>#include <fstream>#include ".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@");// 创建User中的一个角色cn::vicky::model::seri::Person* _person1 = u.add_person();_person1->set_id(1);_person1->set_name("P1");// 创建角色中的一个电话号码:1cn::vicky::model::seri::PhoneNumber* _phone1 = _person1->add_phone();_phone1->set_number("+8613618074943");_phone1->set_type(cn::vicky::model::seri::MOBILE);// 创建角色中的一个电话号码:2cn::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");// 创建角色中的一个电话号码:1cn::vicky::model::seri::PhoneNumber* _phone3 = _person2->add_phone();_phone3->set_number("+8613996398667");_phone3->set_type(cn::vicky::model::seri::MOBILE);// 创建角色中的一个电话号码:2cn::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 secondsc = 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 << () << 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@*+\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@*P1           直接打印二进制数据是不正确的!!!
+8613618074943
---------------------------
1
Jack
123456
---------------------------
1
P1
+8613618074943
02882334717
---------------------------
2
P2
+8613996398667
02882334717
---------------------------

Great...那么,protobuf 与 redis的结合成功了!

个人认为,这种面向对象,并且跨语言,在存储和读取依赖redis内存数据库的基础上是非常的高性能!


google protocol buffer 与 redis 结合使用

google protocol buffer 与 redis 结合使用  讨论


Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析

一、问题:数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求。 二、解决方案: 1.通过高速服务器Cache缓存数据库数据 2.内存数据库 (这里仅从数据缓存方面考虑,当...

Redis学习笔记---字符串类型

补充 上篇笔记博客中有些有些关键点未提到,现在这里补充下 redis help 命令 help命令应该是我们使用任何一款软件产品经常用到的命令,有时候通过help命令能够更快的获取相关帮助,而不仅仅通过...

Redis相关知识简介

Redis,一种轻量级键值对数据存储。多数 NoSQL 实现本质上都是键值对,但是 Redis 支持非常丰富的值集,其中包括字符串、列表、集以及散列。因此,Redis 通常被称为 数据结构服务器 。Redis 也以...

google protocol buffer 可以将对象序列化,而redis作为优秀的NOSQL数据库,这里我将以实例方式介绍,将C对象序列化,并存放在redis数据库中! google protocol buffer 的安装以及基础使用可以阅读我上一片文章
------分隔线----------------------------