zoukankan      html  css  js  c++  java
  • C基础 redis缓存访问

    引言

      先说redis安装, 这里采用的环境是.  

    Linux version 4.4.0-22-generic (buildd@lgw01-41) 
    (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) 
    #40-Ubuntu SMP Thu May 12 22:03:46 UTC 2016

     对于 ubuntu 安装 redis是非常简单的. 这里采用源码安装. 安装代码如下

    wget http://download.redis.io/releases/redis-3.0.6.tar.gz
    tar xzf redis-3.0.6.tar.gz
    cd redis-3.0.6
    make

     安装后我的环境是

    那我们测试一下. 安装结果. 先启动 redis-server 服务器.

    再启动 redis-cli 客户端

    我们开始测试一下. 

     测试之后一切正常. redis linux上安装基本完毕了. 更加详细的参照

    Redis 官网教程 很详细 http://www.redis.net.cn/tutorial/3501.html

    前言

      现在我们安装 redis c 访问的驱动. hiredis. 一开始都是下载安装. 我是直接从 hiredis git官网下载安装的.

    hiredis  源码 https://github.com/redis/hiredis

    wget https://github.com/redis/hiredis/archive/master.zip
    unzip master.zip

     安装完毕会看见这样环境

    执行安装命令

    make
    sudo make install

    本质对于 make install 执行了下面步骤

    mkdir -p /usr/local/include/hiredis /usr/local/lib
    cp -a hiredis.h async.h read.h sds.h adapters /usr/local/include/hiredis
    cp -a libhiredis.so /usr/local/lib/libhiredis.so.0.13
    cd /usr/local/lib && ln -sf libhiredis.so.0.13 libhiredis.so
    cp -a libhiredis.a /usr/local/lib
    mkdir -p /usr/local/lib/pkgconfig
    cp -a hiredis.pc /usr/local/lib/pkgconfig

    此刻基本上 hiredis 驱动已经安装完毕. 后面解释一下, 驱动提供的api.

    常用的 api如下.

    /*
     * redis链接函数, 返回redis上下文.
     * ip    : 链接地址的ip
     * port    : 链接端口
     *         : 返回 redis上下文, NULL表示获取失败
     */
    redisContext *redisConnect(const char *ip, int port)
    
    
    /*
     *  执行redis操作命令, 返回得到的结果集
     *    context    : redisConnect 返回的redis上下文对象
     *    format    : 等同于 printf格式控制符
     *    ...        : 后面可变参数, 需要和 format中格式符对应
     *            : 返回 得到的结果集
     */
    void *redisCommand(redisContext *context, const char *format, ...);
    
    /*
     * 释放redis命令操作返回过来的结果集
     * reply    : redisCommand返回的结果集
     */
    void freeReplyObject(void *reply);
    
    /*
     * 释放链接上下文
     * context    : redisConnect返回的链接上下文
     */
    void redisFree(redisContext *context);

     更加详细的解释我们可以看 源码接口文件 hiredis/hiredis.h .  例如

    第一个是 redisConnect 返回的 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;
    
    还有一个是 redisCommand 返回的命令集
    /* 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 */
        int 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;

    关于 hiredis基本的C驱动接口,解释完毕. 后面开始写demo测试一番.最好的理解方式还是看官方源码和测试代码.

    正文

      首先来个简单的demo测试. simpleget.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <hiredis/hiredis.h>
    
    /*
     * 请求 redis网络缓存服务器内存.
     */
    int main(int argc, char* argv[]) {
        redisContext *conn = redisConnect("127.0.0.1", 6379);
        if(NULL == conn) {
            fprintf(stderr, "redisConnect 127.0.0.1:6379 error!
    ");
            exit(EXIT_FAILURE);
        }   
        if(conn->err) {
            fprintf(stderr, "redisConect error:%d
    ", conn->err);
            redisFree(conn);
            exit(EXIT_FAILURE);
        }   
        
        // 这里redisConnect 链接对象创建完毕了
        redisReply *reply = redisCommand(conn, "get foo");
        if(reply && reply->type == REDIS_REPLY_STRING) {
            printf("get foo => %s
    ", reply->str);
        }   
        printf("reply->type = %d
    ", reply->type);
    
        // 释放这个对象
        freeReplyObject(reply);
        // 释放hiredis 上下文对象   
        redisFree(conn);
    
        return 0;
    }

    编译命令是

    gcc -Wall -ggdb -o simpleget.out simpleget.c -lhiredis

    最终测试结果是


    这里表明流程是跑通了. 这里扩展一下, 有时候在Linux上查找函数或宏定义声明好麻烦. 我用的方式是

     find . -name *.h | xargs grep 'REDIS_REPLY_STRING'

    笨方法也挺实用的. 查找的结果是 上面 REDIS_REPLY_STRING 定义在 hiredis/read.h 中 摘录部分如下

    #define REDIS_REPLY_STRING 1
    #define REDIS_REPLY_ARRAY 2
    #define REDIS_REPLY_INTEGER 3
    #define REDIS_REPLY_NIL 4
    #define REDIS_REPLY_STATUS 5
    #define REDIS_REPLY_ERROR 6

     通过这些宏枚举区分返回的值. 其实到这里基本上 关于 redis接口使用基本入门了. 后面再举一个 操作list的操作代码 setlist.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <hiredis/hiredis.h>
    
    /*
     * 请求 redis网络缓存服务器内存.
     */
    int main(int argc, char* argv[]) {
        // 忽略服务器退出,导致当前进程退出
        signal(SIGPIPE, SIG_IGN);
    
        redisContext *conn = redisConnect("127.0.0.1", 6379);
        if(NULL == conn) {
            fprintf(stderr, "redisConnect 127.0.0.1:6379 error!
    ");
            exit(EXIT_FAILURE);
        }   
        if(conn->err) {
            fprintf(stderr, "redisConect error:%d
    ", conn->err);
            redisFree(conn);
            exit(EXIT_FAILURE);
        }   
        
        // 这里redisConnect 链接对象创建完毕了
        freeReplyObject(redisCommand(conn, "lpush mylist foo"));
        freeReplyObject(redisCommand(conn, "lpush mylist bar"));
        redisReply *reply = redisCommand(conn, "lrange mylist 0 -1");
        if(reply && reply->type == REDIS_REPLY_ARRAY && reply->elements == 2) {
            printf("%s %s
    ", reply->element[0]->str, reply->element[1]->str);
        }   
        else {
            printf("redisCommand [lrange mylist 0 -1] error:%d. %s
    ", reply->type, reply->str);
        }   
    
        // 释放这个对象
        freeReplyObject(reply);
        // 释放hiredis 上下文对象   
        redisFree(conn);
    
        return 0;
    }

    编译代码 

    gcc -Wall -ggdb -o setlist.out setlist.c -lhiredis

     运行结果如下

    更加详细介绍请参照 hiredis git上 源码.

    后记

       到这里关于C简单使用控制redis服务器, 基本讲完了. 错误是难免的. 欢迎指正.  

    /**********************************************************************

    **        直接向大师们而不是他们得的学生领悟。 

    **                           —— 阿贝尔

    ***********************************************************************/

  • 相关阅读:
    B1295 [SCOI2009]最长距离 最短路
    B1588 [HNOI2002]营业额统计 set||平衡树
    B1202 [HNOI2005]狡猾的商人 并查集
    B1303 [CQOI2009] 中位数图 数学
    B2002 [Hnoi2010]Bounce 弹飞绵羊 分块
    B1192 [HNOI2006]超级英雄Hero 二分图匹配
    逐个击破
    HAOI2009 毛毛虫
    HNOI/AHOI2018 道路
    NOI2005 瑰丽华尔兹
  • 原文地址:https://www.cnblogs.com/life2refuel/p/5560944.html
Copyright © 2011-2022 走看看