redis整理一--下載、安裝、配置、調用示例


1.redis簡介 

Redis是一個開源(BSD許可),內存存儲的數據結構服務器,可用作數據庫,高速緩存和消息隊列代理。它支持字符串哈希表列表集合有序集合位圖hyperloglogs等數據類型。內置複製、Lua腳本、LRU收回、事務以及不同級別磁盤持久化功能,同時通過Redis Sentinel提供高可用,通過Redis Cluster提供自動分區

注:redis可跨平臺,可運行於windows和linux各版本,作者平臺ubuntu14.04,下載版本爲linux,有興趣讀者可搜索windows上使用方法。

2.redis源碼下載及安裝

2.1.源碼下載

源碼下載地址:選取官網
官網上亦有大量相關介紹,欲進一步學習瞭解,可參閱官網內容。
注:爲配合源碼分析,作者下載的爲redis 3.0版本,下載位置一樣。

2.2.安裝方法

Redis的代碼遵循ANSI-C編寫,可以在所有POSIX系統(如Linux, *BSD, Mac OS X, Solaris等)上安裝運行。而且Redis並不依賴任何非標準庫,也沒有編譯參數必需添加。redis的安裝出奇的簡單,這可能也是他風靡的一個原因,讓人很容易上手,不像某些東西,編譯階段就能讓人完全絕望。

1)解壓:
tar –zxvf redis-2.4.6.tar.gz
編譯
需要說明的事,redis的安裝非常簡單,已經有現成的Makefile文件,直接運行make命令即可。
make
make install
注意安裝權限問題。

2)安裝成功與否測試
終端運行:redis-server,就可以啓用redis服務,可以用netstat命令查看redis監聽的端口(默認是6379)
或調用:ps -aux |grep redis 查看進程

另開啓終端,運行:redis-cli
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>


3.redis配置

redis-server  /etc/path<redis>/redis.conf
注意:修改redis路徑。

作者直接選取其默認配置,未做修改,該部分後續根據需要進行補充,有需要的讀者可參考網上相關文章,亦可參考其官網說明文檔,很詳細。

4.redis使用實例

4.1.redis命令操作

參考redis官網教程。

4.2.linux下C語言調用--hiredis

4.2.1.C語言接口庫下載

Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關係數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。

  在這裏簡單介紹一下redis的C接口庫:C語言接口函數庫hiredis,下載地址:https://github.com/redis/hiredis

hiredis是redis的C接口庫,使用之前我們要先下載安裝hiredis,下載地址:https://github.com/redis/hiredis.git

git clone https://github.com/redis/hiredis.git


下載之後進入hiredis目錄

make

make install


4.2.2.hiredis簡介

下面進行hredis庫中幾個常用函數介紹

(1)redisConnect函數

該函數用於連接redis數據庫

函數原型:

1  redisContext *redisConnect(const char *ip, int port);
2 //說明:該函數用來連接redis數據庫,參數爲數據庫的ip地址和端口,一般redis數據庫的端口爲6379該函數返回一個結構體redisContext。

redisContext結構體定義如下:

 1 /* Context for a connection to Redis */
 2 typedef struct redisContext {
 3     int err; /* Error flags, 0 when there is no error */
 4     char errstr[128]; /* String representation of error when applicable */
 5     int fd; 
 6     int flags;
 7     char *obuf; /* Write buffer */
 8     redisReader *reader; /* Protocol reader */
 9 
10     enum redisConnectionType connection_type;
11     struct timeval *timeout;
12 
13     struct {
14         char *host;
15         char *source_addr;
16         int port;
17     } tcp;
18 
19     struct {
20         char *path;
21     } unix_sock;
22 
23 } redisContext;

(2)redisCommand函數

該函數用於執行redis的命令;

函數原型:

1 void *redisCommand(redisContext *c, const char *format, ...);
2 /*說明:該函數執行命令,就如sql數據庫中的SQL語句一樣,只是執行的是redis數據庫中的操作命令,
3 第一個參數爲連接數據庫時返回的redisContext,
4 後面爲可變參數列表,跟C語言printf函數類似,
5 返回值爲void*,一般強制轉換成爲redisReply類型的進行進一步的處理。*/

用法:

redisReply *reply = (redisReply*)redisCommand(c,   cmd);

redisReply結構體定義如下:

1 /* This is the reply object returned by redisCommand() */
2 typedef struct redisReply {
3     int type; /* REDIS_REPLY_* */
4     long long integer; /* The integer when type is REDIS_REPLY_INTEGER */
5     size_t len; /* Length of string */
6     char *str; /* Used for both REDIS_REPLY_ERROR and REDIS_REPLY_STRING */
7     size_t elements; /* number of elements, for REDIS_REPLY_ARRAY */
8     struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY */
9 } redisReply;

下面是幾種redis的常見錯誤及返回值類型

 1 #define REDIS_ERR -1
 2 #define REDIS_OK 0
 3 #define REDIS_ERR_IO 1 /* Error in read or write */
 4 #define REDIS_ERR_EOF 3 /* End of file */
 5 #define REDIS_ERR_PROTOCOL 4 /* Protocol error */
 6 #define REDIS_ERR_OOM 5 /* Out of memory */
 7 #define REDIS_ERR_OTHER 2 /* Everything else... */
 8     
 9 #define REDIS_REPLY_STRING 1   //返回字符串,查看str,len字段
10 #define REDIS_REPLY_ARRAY 2    //返回一個數組,查看elements的值(數組個數),通過element[index]的方式訪問數組元素,每個數組元素是一個redisReply對象的指針
11 #define REDIS_REPLY_INTEGER 3  //返回整數,從integer字段獲取值
12 #define REDIS_REPLY_NIL 4      //沒有數據返回
13 #define REDIS_REPLY_STATUS 5   //表示狀態,內容通過str字段查看,字符串長度是len字段
14 #define REDIS_REPLY_ERROR 6    //表示出錯,查看出錯信息,如上的str,len字段

(3)redisRelpyObject函數

還函數用於釋放redisCommand返回值redisReply所佔用的內存

1 /* Free a reply object */
2 void freeReplyObject(void *reply)
3 //該函數用於回收釋放redisCommand返回值redisReply所佔用的內存

(4)redisFree函數

該函數用於釋放一個redis數據庫的連接

1 void redisFree(redisContext *c)
2 //用於釋放redisConnect產生的連接

4.2.3.使用示例

下面寫一個簡單的hredis c接口的redis測試程序:
  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stddef.h>  
  4 #include <stdarg.h>  
  5 #include <string.h>  
  6 #include <assert.h>  
  7 #include <hiredis/hiredis.h> //redis C接口庫
  8 
  9 #define REDIS_HOST        "127.0.0.1"
 10 #define REDIS_PORT        6379
 11 
 12 redisContext *g_ctx = NULL;
 13 
 14 int redis_init()
 15 {    
 16     redisContext *c = NULL;
 17     c = redisConnect(REDIS_HOST, REDIS_PORT);
 18     if (NULL == c || c->err) {
 19         if(c) {
 20             printf("Redis [%s:%d], Error:[%s]\n", REDIS_HOST, REDIS_PORT, c->errstr);
 21             redisFree(c);
 22         } else {
 23             printf("Redis [%s:%d] failure\n", REDIS_HOST, REDIS_PORT);
 24         }
 25         return -1;
 26     }
 27     g_ctx = c;
 28     
 29     return 0;
 30 }
 31 
 32 void redis_free()
 33 {
 34     if (g_ctx) {
 35         redisFree(g_ctx);
 36     }
 37     g_ctx = NULL;
 38 }
 39 
 40 int redis_test(const char *cmd)
 41 {
 42     int i = 0;
 43     redisReply *r = NULL;
 44     if (NULL == cmd) {
 45         return -1;
 46     }
 47 
 48     printf("%s\n", cmd);
 49 
 50     r = (redisReply *)redisCommand(g_ctx, cmd);
 51     if (NULL == r) {
 52         printf("%s, Error[%d:%s]", g_ctx->err, g_ctx->errstr);
 53         return -1;
 54     }
 55 
 56     printf("type: %d\n", r->type); 
 57     switch(r->type) {
 58     case REDIS_REPLY_STATUS:
 59         printf("type:%s, reply->len:%d reply->str:%s\n", "REDIS_REPLY_STATUS", r->len, r->str);
 60         break;
 61     case REDIS_REPLY_ERROR:
 62         printf("type:%s, reply->len:%d reply->str:%s\n", "REDIS_REPLY_ERROR", r->len, r->str);
 63         break;
 64     case REDIS_REPLY_INTEGER:
 65         printf("type:%s, reply->integer:%lld\n", "REDIS_REPLY_INTEGER", r->integer);
 66         break;
 67     case REDIS_REPLY_NIL:
 68         printf("type:%s, no data\n", "REDIS_REPLY_NIL");
 69         break;
 70     case REDIS_REPLY_STRING:
 71         printf("type:%s, reply->len:%d reply->str:%s\n", "REDIS_REPLY_STRING", r->len, r->str);
 72         break;
 73     case REDIS_REPLY_ARRAY:
 74         printf("type:%s, reply->elements:%d\n", "REDIS_REPLY_ARRAY", r->elements);
 75         for (i = 0; i < r->elements; i++) {
 76             printf("%d: %s\n", i, r->element[i]->str);
 77         }
 78         break;
 79     default:
 80         printf("unkonwn type:%s\n", r->type);
 81         break;
 82     }
 83  
 84     /*release reply and context */
 85     freeReplyObject(r); 
 86     return 0; 
 87 }
 88 
 89 int main()
 90 {
 91     const char *cmd = NULL;
 92 
 93     /* init redis */
 94     if (redis_init()) {
 95         return -1;
 96     }
 97 
 98     /* 1: SET<--->GET */
 99     printf("SET<--->GET\n");
100     cmd = "set foo bar";
101     redis_test(cmd);
102     cmd = "get foo";
103     redis_test(cmd);
104 
105     /* 2: SADD<--->SMEMBERS */
106     printf("\nSADD<--->SMEMBERS\n");
107     cmd = "SADD namelist jack lily lucy tom";
108     redis_test(cmd);
109     cmd = "SMEMBERS namelist";
110     redis_test(cmd);
111     
112     /* 3: .....*/
113     
114     /* free redis context */
115     redis_free();
116     
117     return 0;
118 }

運行結果:

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


5.參考文章









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章