转载自:http://www.cnblogs.com/wenqiang/p/5506744.html
如有侵权、请联系。
一、redis简介
Redis是一个key-value存储系统。和 Memcached类似,但是解决了断电后数据完全丢失的情况,而且她支持更多无化的value类型,除了和string外,还支持lists(链表)、 sets(集合)和zsets(有序集合)几种数据类型。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作, 而且这些操作都是原子性的。
二、redis的安装
首先从在官网下载redis源码安装包,下载地址:https://github.com/antirez/redis.git
目前最新分支为3.2
git clone -b 3.2 https://github.com/antirez/redis.git下载完成之后进入redis目录,编译安装直接是
make
make install
编译安装完成直接运行
redis-server就可以启用redis服务,可以用netstat命令查看redis监听的端口(默认是6379)
redis服务起来之后我就可以进行相应的测试看数据库是否安装成功:
在命令行输入redis-cli启用redis客户端:
输入一下命令测试redis是否安装成功
127.0.0.1:6379> ping PONG 127.0.0.1:6379> set test hello OK 127.0.0.1:6379> get test "hello" 127.0.0.1:6379>更多redis命令请参考redis命令手册,这上面详细介绍了redis-cli各种命令的用法
http://doc.redisfans.com/
至此,redis数据库安装完成
三、redis c 接口库的安装
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便
在这里简单介绍一下redis的C接口库:
hiredis是redis的C接口库,使用之前我们要先下载安装hiredis,下载地址:https://github.com/redis/hiredis.git
git clone https://github.com/redis/hiredis.git下载之后进入hiredis目录
make
make install
下面进行hredis库中几个常用函数介绍
(1)redisConnect函数
该函数用于连接redis数据库
函数原型:
redisContext *redisConnect(const char *ip, int port); //说明:该函数用来连接redis数据库,参数为数据库的ip地址和端口,一般redis数据库的端口为6379该函数返回一个结构体redisContext。redisContext结构体定义如下:
/* Context for a connection to Redis */ typedef struct redisContext { int err; /* Error flags, 0 when there is no error */ char errstr[128]; /* String representation of error when applicable */ int fd; int flags; char *obuf; /* Write buffer */ redisReader *reader; /* Protocol reader */ enum redisConnectionType connection_type; struct timeval *timeout; struct { char *host; char *source_addr; int port; } tcp; struct { char *path; } unix_sock; } redisContext;(2)redisCommand函数
该函数用于执行redis的命令;
函数原型:
void *redisCommand(redisContext *c, const char *format, ...); /*说明:该函数执行命令,就如sql数据库中的SQL语句一样,只是执行的是redis数据库中的操作命令, 第一个参数为连接数据库时返回的redisContext, 后面为可变参数列表,跟C语言printf函数类似, 返回值为void*,一般强制转换成为redisReply类型的进行进一步的处理。*/用法:
redisReply *reply = (redisReply*)redisCommand(c, cmd);
redisReply结构体定义如下:
/* This is the reply object returned by redisCommand() */ typedef struct redisReply { int type; /* REDIS_REPLY_* */ long long integer; /* The integer when type is REDIS_REPLY_INTEGER */ size_t len; /* Length of string */ char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */ size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */ struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */ } redisReply;
下面是几种redis的常见错误及返回值类型
#define REDIS_ERR -1 #define REDIS_OK 0 #define REDIS_ERR_IO 1 /* Error in read or write */ #define REDIS_ERR_EOF 3 /* End of file */ #define REDIS_ERR_PROTOCOL 4 /* Protocol error */ #define REDIS_ERR_OOM 5 /* Out of memory */ #define REDIS_ERR_OTHER 2 /* Everything else... */ #define REDIS_REPLY_STRING 1 //返回字符串,查看str,len字段 #define REDIS_REPLY_ARRAY 2 //返回一个数组,查看elements的值(数组个数),通过element[index]的方式访问数组元素,每个数组元素是一个redisReply对象的指针 #define REDIS_REPLY_INTEGER 3 //返回整数,从integer字段获取值 #define REDIS_REPLY_NIL 4 //没有数据返回 #define REDIS_REPLY_STATUS 5 //表示状态,内容通过str字段查看,字符串长度是len字段 #define REDIS_REPLY_ERROR 6 //表示出错,查看出错信息,如上的str,len字段(3)redisRelpyObject函数
还函数用于释放redisCommand返回值redisReply所占用的内存
/* Free a reply object */ void freeReplyObject(void *reply) //该函数用于回收释放redisCommand返回值redisReply所占用的内存(4)redisFree函数
该函数用于释放一个redis数据库的连接
void redisFree(redisContext *c) //用于释放redisConnect产生的连接下面写一个简单的hredis c接口的redis测试程序:
#include <stdio.h> #include <string.h> #include <stddef.h> #include <stdarg.h> #include <string.h> #include <assert.h> #include <hiredis/hiredis.h> //redis C接口库 #define REDIS_HOST "127.0.0.1" #define REDIS_PORT 6379 redisContext *g_ctx = NULL; int redis_init() { redisContext *c = NULL; c = redisConnect(REDIS_HOST, REDIS_PORT); if (NULL == c || c->err) { if(c) { printf("Redis [%s:%d], Error:[%s]\n", REDIS_HOST, REDIS_PORT, c->errstr); redisFree(c); } else { printf("Redis [%s:%d] failure\n", REDIS_HOST, REDIS_PORT); } return -1; } g_ctx = c; return 0; } void redis_free() { if (g_ctx) { redisFree(g_ctx); } g_ctx = NULL; } int redis_test(const char *cmd) { int i = 0; redisReply *r = NULL; if (NULL == cmd) { return -1; } printf("%s\n", cmd); r = (redisReply *)redisCommand(g_ctx, cmd); if (NULL == r) { printf("%s, Error[%d:%s]", g_ctx->err, g_ctx->errstr); return -1; } printf("type: %d\n", r->type); switch(r->type) { case REDIS_REPLY_STATUS: printf("type:%s, reply->len:%d reply->str:%s\n", "REDIS_REPLY_STATUS", r->len, r->str); break; case REDIS_REPLY_ERROR: printf("type:%s, reply->len:%d reply->str:%s\n", "REDIS_REPLY_ERROR", r->len, r->str); break; case REDIS_REPLY_INTEGER: printf("type:%s, reply->integer:%lld\n", "REDIS_REPLY_INTEGER", r->integer); break; case REDIS_REPLY_NIL: printf("type:%s, no data\n", "REDIS_REPLY_NIL"); break; case REDIS_REPLY_STRING: printf("type:%s, reply->len:%d reply->str:%s\n", "REDIS_REPLY_STRING", r->len, r->str); break; case REDIS_REPLY_ARRAY: printf("type:%s, reply->elements:%d\n", "REDIS_REPLY_ARRAY", r->elements); for (i = 0; i < r->elements; i++) { printf("%d: %s\n", i, r->element[i]->str); } break; default: printf("unkonwn type:%s\n", r->type); break; } /*release reply and context */ freeReplyObject(r); return 0; } int main() { const char *cmd = NULL; /* init redis */ if (redis_init()) { return -1; } /* 1: SET<--->GET */ printf("SET<--->GET\n"); cmd = "set foo bar"; redis_test(cmd); cmd = "get foo"; redis_test(cmd); /* 2: SADD<--->SMEMBERS */ printf("\nSADD<--->SMEMBERS\n"); cmd = "SADD namelist jack lily lucy tom"; redis_test(cmd); cmd = "SMEMBERS namelist"; redis_test(cmd); /* 3: .....*/ /* free redis context */ redis_free(); return 0; }运行结果:
SET<--->GET set foo bar type: 5 type:REDIS_REPLY_STATUS, reply->len:2 reply->str:OK get foo type: 1 type:REDIS_REPLY_STRING, reply->len:3 reply->str:bar SADD<--->SMEMBERS SADD namelist jack lily lucy tom type: 3 type:REDIS_REPLY_INTEGER, reply->integer:0 SMEMBERS namelist type: 2 type:REDIS_REPLY_ARRAY, reply->elements:4 0: lucy 1: jack 2: lily 3: tom