redis 学习-hiredis库使用(二)

Redis是一个非关系型(NoSQL)数据库,本文将实现一个用c++ API接口连接的例子,来实现对Redis数据库的写入和读出功能,具体将从Redis的安装,Redis的c++接口hiredis安装,代码演示三部分组成。

一、Redis的安装和配置


    由于源中已有Redis的相关组件,这里就不进行源码编译而直接使用apt-get (ubuntu环境)下载和安装

1.redis的安装和配置
sudo apt-cache search redis        //根据结果列表找到需要安装的软件包:redis-server
sudo apt-get install redis-server  //安装软件
 
2.配置文件
whereis resids                    //查看redis位置: /etc/redis
cd  /etc/redis                    //进入文件夹
/etc/redis$ ls -l                 //显示文件,其中redis.conf为配置文件
总用量 60
-rw-r----- 1 redis redis 41623 12月 19  2015 redis.conf
drwxr-xr-x 2 root  root   4096 9月  21 10:47 redis-server.post-down.d
drwxr-xr-x 2 root  root   4096 9月  21 10:47 redis-server.post-up.d
drwxr-xr-x 2 root  root   4096 9月  21 10:47 redis-server.pre-down.d
drwxr-xr-x 2 root  root   4096 9月  21 10:47 redis-server.pre-up.d
 
3.启动
服务端:redis-server (使用默认端口) (--port 6599 加端口)
客户端:redis-cli    (连接之前测试启动指令 redis-cli ping 返回PONG启动成功)
 
4.关闭:redis-cli    (-p 6380 可指定端口)shutdown


二、redis的c++api接口 hiredis安装


    实际上hiredis是一个c的接口,同样使用apt-get安装hiredis。

sudo apt-cache search hiredis // 查看发现c语言开发库为libhiredis-dev
libhiredis-dbg - minimalistic C client library for Redis (debug)
libhiredis-dev - minimalistic C client library for Redis (development files)
libhiredis0.13 - minimalistic C client library for Redis
python-hiredis - redis protocol reader for Python 2.X using hiredis
 
sudo apt-get install libhiredis-dev  //选择并安装
     hiredis库目录的位置为默认的 /usr/lib/x86_64-linux-gnu/下,头文件在 /usr/include/hiredis 下,hiredis头文件中定义了Redis的连接的方式redisConnect()等方法,连接信息存储在上下文redisContext的结构体对象中,通过redisCommand()等方法进行具体的数据库存取指令操作并返回相关信息在redisReply的结构体对象中,不要忘了freeReplyObject(void *reply)释放redisReply连接响应对象,redisFree()函数释放redisContext上下文对象,具体的定义和方法请看以下代码。

#ifndef __HIREDIS_H
#define __HIREDIS_H
#include "read.h"
#include /* for va_list */
#include /* for struct timeval */
#include /* uintXX_t, etc */
#include "sds.h" /* for sds */
 
#define HIREDIS_MAJOR 0
#define HIREDIS_MINOR 13
#define HIREDIS_PATCH 3
#define HIREDIS_SONAME 0.13
 
#ifdef __cplusplus
extern "C" {
#endif
 
/* This is the reply object returned by redisCommand()
执行redis数据库指令操作的响应信息封装在redisReply的结构体中
 */
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 错误信息和返回的string类型*/
    size_t elements; /* number of elements, for REDIS_REPLY_ARRAY 如果为数组存储数组长度*/
    struct redisReply **element; /* elements vector for REDIS_REPLY_ARRAY 存储数组元素向量*/
} redisReply;
 
redisReader *redisReaderCreate(void);
 
/* Function to free the reply objects hiredis returns by default.
   释放响应对象
 */
void freeReplyObject(void *reply);
 
/* Functions to format a command according to the protocol.
   数据库操作相关语句
 */
int redisvFormatCommand(char **target, const char *format, va_list ap);
int redisFormatCommand(char **target, const char *format, ...);
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
void redisFreeCommand(char *cmd);
void redisFreeSdsCommand(sds cmd);
 
enum redisConnectionType {
    REDIS_CONN_TCP,
    REDIS_CONN_UNIX,
};
 
/* Context for a connection to Redis
    建立上下文连接对象的结构体
 */
typedef struct redisContext {
    int err; /* Error flags, 0 when there is no error错误标志,0表示没有错误 */
    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;
 
//建立上下文连接

// 与inet的连接
redisContext *redisConnect(const char *ip, int port);
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
redisContext *redisConnectNonBlock(const char *ip, int port);
redisContext *redisConnectBindNonBlock(const char *ip, int port,
                                       const char *source_addr);
redisContext *redisConnectBindNonBlockWithReuse(const char *ip, int port,
                                                const char *source_addr);

//与unix的连接
redisContext *redisConnectUnix(const char *path);
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
redisContext *redisConnectUnixNonBlock(const char *path);
redisContext *redisConnectFd(int fd);
 
/**
 * Reconnect the given context using the saved information.
 *
 * This re-uses the exact same connect options as in the initial connection.
 * host, ip (or path), timeout and bind address are reused,
 * flags are used unmodified from the existing context.
 *
 * Returns REDIS_OK on successfull connect or REDIS_ERR otherwise.
 */
int redisReconnect(redisContext *c);
 
int redisSetTimeout(redisContext *c, const struct timeval tv);
int redisEnableKeepAlive(redisContext *c);
void redisFree(redisContext *c);
int redisFreeKeepFd(redisContext *c);
int redisBufferRead(redisContext *c);
int redisBufferWrite(redisContext *c, int *done);
 
/* In a blocking context, this function first checks if there are unconsumed
 * replies to return and returns one if so. Otherwise, it flushes the output
 * buffer to the socket and reads until it has a reply. In a non-blocking
 * context, it will return unconsumed replies until there are no more. */
int redisGetReply(redisContext *c, void **reply);
int redisGetReplyFromReader(redisContext *c, void **reply);
 
/* Write a formatted command to the output buffer. Use these functions in blocking mode  to get a pipeline of commands. */
int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
 
/* Write a command to the output buffer. Use these functions in blocking mode
 * to get a pipeline of commands. */
int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
int redisAppendCommand(redisContext *c, const char *format, ...);
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
 
/* Issue a command to Redis. In a blocking context, it is identical to calling
 * redisAppendCommand, followed by redisGetReply. The function will return
 * NULL if there was an error in performing the request, otherwise it will
 * return the reply. In a non-blocking context, it is identical to calling
 * only redisAppendCommand and will always return NULL. */
void *redisvCommand(redisContext *c, const char *format, va_list ap);
void *redisCommand(redisContext *c, const char *format, ...);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
 
#ifdef __cplusplus
}
#endif
 
#endif


    在read.h文件中有redisReply结构体宏的定义,int type的类型:

#ifndef __HIREDIS_READ_H
#define __HIREDIS_READ_H
 
#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    //存放在char *str
#define REDIS_REPLY_ARRAY 2
#define REDIS_REPLY_INTEGER 3   //integer存储为数据条数
#define REDIS_REPLY_NIL 4
#define REDIS_REPLY_STATUS 5   //成功状态码为:"OK"  存放在char *str
#define REDIS_REPLY_ERROR 6    //存放在char *str


     如hiredis.c文件中看freeReplyObject函数对以上响应状态的处理:

/* Free a reply object 
redisReply的类型有:REDIS_REPLY_INTEGER:
REDIS_REPLY_ERROR:
REDIS_REPLY_STATUS:
REDIS_REPLY_STRING:这三个都是返回字符串
*/
void freeReplyObject(void *reply) {
    redisReply *r = reply;
    size_t j;
 
    if (r == NULL)
        return;
 
    switch(r->type) {
    case REDIS_REPLY_INTEGER:
        break; /* Nothing to free */
    case REDIS_REPLY_ARRAY:
        if (r->element != NULL) {
            for (j = 0; j < r->elements; j++)
                freeReplyObject(r->element[j]);
            free(r->element);
        }
        break;
    case REDIS_REPLY_ERROR:
    case REDIS_REPLY_STATUS:
    case REDIS_REPLY_STRING:
        free(r->str);
        break;
    }
    free(r);
}


三、Redis使用hiredis API连接


代码结构如图所示:

redis 学习-hiredis库使用(二)_第1张图片

具体代码如下:配置文件

#ifndef REDISCONFIG_H
#define REDISCONFIG_H
#include
 
class RedisConfig
{
public:
    RedisConfig();
    std::string getRedisIP();//获取ip
    int getRedisPort();//获取端口号
 
};
 
#endif
#include "RedisConfig.h"
#include
 
RedisConfig::RedisConfig()
{
 
}
 
std::string RedisConfig::getRedisIP()
{
    return "127.0.0.1";//设置为本机ip
}
 
int RedisConfig::getRedisPort()
{
    return 6379;
}
    具体处理代码:包含了string类型和list类型的存取代码,根据redisReply响应的信息来进行信息的处理,对于其他类型对响应状态的判断可以通过命令行操作来确定,如图1所示。

#ifndef _H_REDIS_TOOLS_
#define _H_REDIS_TOOLS_
#include
#include
#include
#include
 
using namespace std;
 
class RedisTool
{
public:
    RedisTool();
    ~RedisTool();
    int setString(string key, string value);
    string getString(string key);
 
    int setList(string key,vector value);
    vector getList(string key);
 
private:
    void init();
    redisContext *m_redis;
    RedisConfig m_config;
};
 
#endif
#include
#include
#include
#include
#include
 
RedisTool::RedisTool()
{
    m_redis = NULL;
    init();
}
RedisTool::~RedisTool()
{
    if(m_redis != NULL)
    {
        redisFree(m_redis);//析构函数释放资源
        cout << "~RedisTool :: free redis connection " << endl;
    }
}
 
void RedisTool::init()
{
    struct timeval timeout = { 1, 500000 }; // 1.5 seconds 设置连接等待时间
    char ip[255];    
    strcpy(ip, m_config.getRedisIP().c_str());
    cout << "init : ip = " << ip << endl;
    m_redis = redisConnectWithTimeout(ip, m_config.getRedisPort(), timeout);//建立连接
    if (m_redis->err) {
        printf("RedisTool : Connection error: %s\n", m_redis->errstr);
    }    
    else
    {
        cout << "init redis tool success " << endl;
        //REDIS_REPLY响应的类型type
        cout << "#define REDIS_REPLY_STRING 1"<< endl;
        cout << "#define REDIS_REPLY_ARRAY 2"<< endl;
        cout << "#define REDIS_REPLY_INTEGER 3"<< endl;
        cout << "#define REDIS_REPLY_NIL 4"<< endl;
        cout << "#define REDIS_REPLY_STATUS 5"<< endl;
        cout << "#define REDIS_REPLY_ERROR 6"<< endl;
    }
}
 
//向数据库写入string类型数据
int RedisTool::setString(string key, string value)
{
    if(m_redis == NULL || m_redis->err)//int err; /* Error flags, 错误标识,0表示无错误 */
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return -1;
    }
    redisReply *reply;
    reply = (redisReply *)redisCommand(m_redis,"SET %s %s", key.c_str(), value.c_str());//执行写入命令
    cout<<"set string type = "<type<     int result = 0;
    if(reply == NULL)
    {
        redisFree(m_redis);
        m_redis = NULL;
        result = -1;
        cout << "set string fail : reply->str = NULL " << endl;
        //pthread_spin_unlock(&m_redis_flock);
        return -1;
    }
    else if(strcmp(reply->str, "OK") == 0)//根据不同的响应类型进行判断获取成功与否
    {
        result = 1;
    }
    else
    {
        result = -1;
        cout << "set string fail :" << reply->str << endl;
    }
    freeReplyObject(reply);//释放响应信息
 
    return result;
}
 
//从数据库读出string类型数据
string RedisTool::getString(string key)
{
    if(m_redis == NULL || m_redis->err)
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return NULL;
    }
    redisReply *reply;
    reply = (redisReply *)redisCommand(m_redis,"GET %s", key.c_str());
    cout<<"get string type = "<type<  
    if(reply == NULL)
    {
        redisFree(m_redis);
        m_redis = NULL;
        cout << "ERROR getString: reply = NULL!!!!!!!!!!!! maybe redis server is down" << endl;
        return NULL;
    }
    else if(reply->len <= 0)
    {        
        freeReplyObject(reply);
        return NULL;
    }
    else
    {
        stringstream ss;
        ss << reply->str;
        freeReplyObject(reply);
        return ss.str();
    }
}
 
//向数据库写入vector(list)类型数据
int RedisTool::setList(string key,vector value)
{
    if(m_redis == NULL || m_redis->err)
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return -1;
    }
 
    redisReply *reply;
 
    int valueSize = value.size();
    int result = 0;
 
    for(int i=0; i     {
        reply = (redisReply*)redisCommand(m_redis,"RPUSH %s %d", key.c_str(),value.at(i));
        cout<<"set list type = "<type<<" ";
        int old = reply->integer;
        if(reply == NULL)
        {
            redisFree(m_redis);
            m_redis = NULL;
            result = -1;
            cout << "set list fail : reply->str = NULL " << endl;
            //pthread_spin_unlock(&m_redis_flock);
            return -1;
        }
        else if(reply->integer == old++)
        {
            result = 1;
            cout<<"rpush list ok"<             continue;
        }
        else
        {
            result = -1;
            cout << "set list fail ,reply->integer = " << reply->integer << endl;
            return -1;
        }
 
    }
 
    freeReplyObject(reply);
    cout<<"set List  success"<     return result;
 
}
 
//从数据库读出vector(list)类型数据
vector RedisTool::getList(string key)
{
 
    if(m_redis == NULL || m_redis->err)
    {
        cout << "Redis init Error !!!" << endl;
        init();
        return vector{};//返回空的向量
    }
 
    redisReply *reply;
    reply = (redisReply*)redisCommand(m_redis,"LLEN %s", key.c_str());
    int valueSize = reply->integer;
    cout<<"List size is :"<integer<  
    reply = (redisReply*)redisCommand(m_redis,"LRANGE %s %d %d", key.c_str(),0,valueSize-1);
    cout<<"get list type = "<type<     cout<<"get list size = "<elements<  
    redisReply** replyVector = reply->element;//获取数组指针
    vector result;
    for(int i=0;i     {
        string temp =(*replyVector)->str;//遍历redisReply*数组,存入vector向量
        int a =atoi(temp.c_str());
        result.push_back(a);
        replyVector++;
    }
 
    cout<<"result size:"<     return result;
 
}
    main函数:

#include
#include
#include
 
using namespace std;
 
 
int main()
{
    RedisTool redis;
    //测试 string
    redis.setString("wangbaojia","test1");
    string result = redis.getString("wangbaojia");
    cout<<"result="<     //测试list
    vector vec ={1,2,3,4};
    redis.setList("bao",vec);
    vector vecResult = redis.getList("bao");
    for(int i=0;i     {
        cout<     }
 
    return 0;
}
      运行结果:

redis 学习-hiredis库使用(二)_第2张图片

 

 

最近抽时间把hiredis给封装了一下,便于编程,不用每次都查命令

redis命令查询地址:http://doc.redisfans.com/index.html

源码部分稍后会上传到资源包位置。
/*

* redis_interface.h
*
*/


#ifndef REDIS_INTERFACE_H_
#define REDIS_INTERFACE_H_


#include
#include
#include
#include
#include


#include "hiredis/hiredis.h"
#include "../h/types.h"
#include "../h/mutex.h"


using namespace std;


namespace ws_redis
{
#define WS_REDIS_LOG_LENGTH_MAX 2048  // redis log最大长度
#define WS_REDIS_CONTEXT_HASH_MARK 5381  // redis连接hash查找掩码


//--------------------------------------------------------
// reids命令实行时间检测器
//--------------------------------------------------------
class RedisCmdTimeTesting
{
public:
RedisCmdTimeTesting();
virtual ~RedisCmdTimeTesting();
void Log(PRedisContext pRD, const char* fmt, ...); // cmd执行命令log


private:
std::string   m_log;  // 日志
timeval m_begin;  // 起始时间
timeval m_end;  // 结束时间
};


//--------------------------------------------------------
// reids 执行报告记录器
//--------------------------------------------------------
struct RedisReport_t
{
uint32_t m_State;  // 报告状态0表示关闭,1表示开启
uint32_t m_Pid;  // 监控线程pid
uint32_t m_RunCount;  // 执行总数
uint64_t m_RunTime;  // 执行时间(所有语句执行的时间和)
uint64_t m_StartTime;  // 起始时间
map >  m_KeyInfo;  // 同一条语句执行的次数和时间>
RedisReport_t() :m_State(0), m_Pid(0), m_RunCount(0), m_StartTime(0)
{
m_KeyInfo.clear();
}
};


struct SortData
{
std::string m_number;  //对应sortedSet的member
std::string m_score;  //对应sortedSet的score
};


//--------------------------------------------------------
// reids 连接管理器
//--------------------------------------------------------
class RedisManager
{
public:
static RedisManager & Instence(void)
{
static RedisManager obj;
return obj;
}  
public:  
// -----------------redis连接相关---------------------
uint32_t CreateContext(std::string ip, uint32_t port);  // 创建链接
uint32_t CreateContextWithOutTime(std::string ip, uint32_t port, uint32_t time); // 建立链接,带超时时间
bool CloseContext(uint32_t index_link);  // 指定管理某个链接
bool CloseAllContext();  // 关闭所有链接
PRedisContext getRedis(std::string key);  // 根据key获取redis连接(多连接情况下)通过hash key找到该key存储的redis连接,并发情况下可以提高并发率
PRedisContext getRedis(uint32_t index_link);  // 直接指明hashmap中第几个redis连接
bool selectDB(PRedisContext& pRD, uint32_t index_db);  // 获取指定redis连接中的第N个DB


// -----------------tool工具--------------------------
std::string contextAddrInfo(PRedisContext& pRD);  // 链接信息
std::string replayInfo(redisReply* pReply);  // 报告信息
std::string replaceCmdCrlf(const char* format);  // 将命令中的一些符号替换掉


// -----------------redis命令相关---------------------
redisReply* redisCommand(PRedisContext& pRD, const char *format, ...);
// key
bool getAllKeys(PRedisContext& pRD, set& value, std::string strMatching = "*");  // (消耗性能)获取数据库中所有的key;  value: 为返回的所有key集合, strMatching:为查找匹配,默认为"*"所有,可以为如"t[w]*"表达式
bool isKeyExist(PRedisContext& pRD, const string& key, bool& keyExist);  // 检查key是否存在
bool delKey(PRedisContext& pRD, const std::string& key);  // 删除指定的key
bool keyType(PRedisContext& pRD, const std::string& key, std::string& type);  // 获取key的类型;返回值:none(key不存在),std::string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
bool setKeyTTL(PRedisContext& pRD, const std::string& key, uint32_t time);  // 设置key的生存时间,单位s
bool expireAt(PRedisContext& pRD, const std::string& key, time_t calTime);  // 更新key的生存时间, 单位time;
uint32_t delKey_T(PRedisContext& pRD, const std::string& key);  // 事务模式:删除指定的key, 返回0表示失败, 1表示成功, 2表示存入队列(因为有事务处理)


// lock 模拟,阻塞(最大阻塞2秒)
bool lock(PRedisContext& pRD, const std::string &key, uint32_t ttl);  // 加锁
bool unlock(PRedisContext& pRD, const std::string &key);  // 解锁


//--- string
bool setStrValue(PRedisContext& pRD, const std::string& key, const std::string& value);  // 设置key-value
bool setStrValue(PRedisContext& pRD, const std::string& key, const std::string& value, const uint32_t& time);// 设置key-value,带时间
bool getStrValue(PRedisContext& pRD, const std::string& key, std::string& value);  // 获取key-value
bool setAnyValue(PRedisContext &pRD, map value);  // 一次插入多个值
bool getAnyValue(PRedisContext& pRD, const set& setKeys, map& outMapInfo); // 一次获取多个数据的值  
bool incrValue(PRedisContext& pRD, const std::string& key, int incrNum = 1);  // 每次增加指定值,默认为1
bool incrValue(PRedisContext& pRD, const std::string& key, long long &outValue, int incrNum = 1);  // 每次增加指定值,默认为1,返回增加后的值
bool decrValue(PRedisContext& pRD, const std::string& key, int decrNum = 1);  // 每次减去指定值,默认为1
bool decrValue(PRedisContext& pRD, const std::string& key, long long &outValue, int decrNum = 1);  // 每次减去指定值,默认为1,返回增加后的值


//--- list
bool getListLen(PRedisContext& pRD, const std::string& key, uint32_t& len);  // 获取list长度
bool lPushList(PRedisContext& pRD, const std::string& key, std::string& value);  // 插入表头,表为空创建
bool rPushList(PRedisContext& pRD, const std::string& key, std::string& value);  // 插入表尾,表为空创建
bool lPushXList(PRedisContext& pRD, const std::string& key, std::string& value);  // 插入表头,表为空不创建
bool rPushXList(PRedisContext& pRD, const std::string& key, std::string& value);  // 插入表尾,表为空创建
bool lPushAnyList(PRedisContext& pRD, const std::string& key, vector& values);  // 插入多个值到表头,先插入数据在表尾
bool rPushAnyList(PRedisContext& pRD, const std::string& key, vector& values);  // 插入多个值到表尾,先插入数据在表头
bool lPushGetLen(PRedisContext& pRD, const std::string& key, std::string& value, uint32_t& len);  // 插入表头并获取长度
bool rPushGetLen(PRedisContext& pRD, const std::string& key, std::string& value, uint32_t& len);  // 插入表尾并获取长度
bool rPushListBit(PRedisContext& pRD, const std::string& key, std::string& binMem);  // (二进制)插入单个字符列到list尾部,如"a b c"
bool lPopListBit(PRedisContext& pRD, const std::string& key, std::string& binMem, bool& keyExist);  // (二进制)移除字符列, keyExist 判断是否获取字符
bool rPopList(PRedisContext& pRD, const std::string& key, std::string& value, bool& keyExist);  // 移除表尾的元素
bool lPopList(PRedisContext& pRD, const std::string& key, std::string& value, bool& keyExist);  // 移除表头的元素
bool lremList(PRedisContext& pRD, const std::string& key, std::string& value, std::string count = "1"); // 移除与value值相同的元素,count为移除个数(正数表示从前到后移除n个,负数表示从后往前移除n个,0表示移除所有)
bool lrangeList(PRedisContext& pRD, const std::string& key, std::vector& result, uint32_t startPos = 0, uint32_t endPos = 0); // 返回指定区域内的元素列表

//--- hash
bool setHashValue(PRedisContext& pRD, const std::string& key, std::string field, std::string strValue); // 设置hash值
bool getHashValue(PRedisContext& pRD, const std::string& key, std::string field, std::string& strValue);// 获取hash值
bool setAnyHashValue(PRedisContext& pRD, const std::string& key, map& values);// 设置多个值
bool getAnyHashValue(PRedisContext& pRD, const std::string& key, vector& fields, map& values); // 获取多个值
bool getHashAllValue(PRedisContext& pRD, const std::string& key, map& valueMap); // 获取所有hash值对
bool getHashAllFields(PRedisContext& pRD, const std::string& key, vector& fields);  // 获取目标key的所有field
bool setHashValueBit(PRedisContext& pRD, const std::string& key, std::string field, std::string binValue);// (二进制)设置hash值
bool getAnyHashValueBit(PRedisContext& pRD, const std::string& key, map& valueMap);// (二进制)获取所有键值对
bool delHashValue(PRedisContext& pRD, const std::string& key, std::string field);  // 删除hash值
bool delHashValue(PRedisContext& pRD, const std::string& key, const set & fields, int64_t& rmCount);// 删除多个hash值
bool isMemInHash(PRedisContext& pRD, const std::string& key, std::string field, bool& isMem);  // 判断是不是hash成员
bool incrHashValue(PRedisContext& pRD,const std::string& key, std::string field,std::string value = "1");// 在原始值上增加指定值
bool setHashValue_T(PRedisContext& pRD, const std::string& key, map& fieldValue); // (事务) 设置hash值


//--- set
bool isMemInSet(PRedisContext& pRD, const std::string& key, std::string& value, bool& isMem);  // 判断是不是set成员
bool getSetCount(PRedisContext& pRD, const std::string& key, uint32_t& count, bool& keyExist);  // 获取set元素个数
bool setSetValue(PRedisContext& pRD, const std::string& key, std::string& value);  // 添加元素,已经存在的元素被忽略
bool setAnySetValue(PRedisContext& pRD, const std::string& key, set& value);  // 添加多个值,已经存在的元素被忽略
bool getAnySetValue(PRedisContext& pRD, const std::string& key, set& value);  // 获取set集合
bool remSetValue(PRedisContext& pRD, const std::string& key, std::string& value);  // 移除集合中的元素
bool remAnySetValue(PRedisContext& pRD, const std::string &key, const std::set &value);  // 移除多个指定元素
bool getSetSunion(PRedisContext& pRD, set& keys, set& value);  // 获取多个key的并集
bool getSetSdiff(PRedisContext& pRD, set& keys, set& value);  // 获取多个key的差集
bool getSetSinter(PRedisContext& pRD, set& keys, set& value);  // 获取多个key的交集
bool setSetValue_T(PRedisContext& pRD, const std::string& key, std::string& value);  // (事务)添加集合元素

// --- sortset  
bool isMemInSortedSet(PRedisContext& pRD, const std::string& key, const std::string& member, bool& isMem); // 检查目标是不是sortset的资源
bool getCountSortedSet(PRedisContext& pRD, const std::string& key, uint32_t& totalCount);  // 获取资源个数
bool setSortSet(PRedisContext& pRD, const std::string& key, std::string& mem, const uint64_t& score);  // 添加元素到key
bool setAnySortSet(PRedisContext& pRD, const std::string& key, const map& scores);// 添加多个元素到key
bool incrSortSet(PRedisContext& pRD, const std::string& key, const std::string& mem, const uint32_t& incrScore);// 给指定元素增加incrScore的值  
bool decrScore(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& decrScore); //减少资源的排序值
bool remMemFromSortedSet(PRedisContext& pRD, const std::string& key, const std::string& mem);            // 删除指定资源
bool remRangeByScore(PRedisContext& pRD, const std::string& key, const uint32_t& min, const uint32_t& max); // 删除资源排序值域的资源
bool getScoreByMember(PRedisContext& pRD, const std::string& key, const std::string& member, uint32_t& score); // 返回指定资源的排序值(注意是值不是排名)
bool getDescRankByMember(PRedisContext& pRD, const std::string& key, const std::string& member, uint32_t& rank); // 获取资源的降序排名
bool getAscRankByMember(PRedisContext& pRD, const std::string& key, const std::string& member, uint32_t& rank); // 获取资源升序排名
bool incrSortSetBit(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& incrScore);  // (二进制)给指定元素增加incrScore的值
bool getDescSortedData(PRedisContext& pRD, const std::string& key, const uint32_t& offset, const uint32_t& limit, std::vector& datas); // (降序)从大到小获取指定段的数据, 0 score 会被过滤掉
bool getDescSortedAllData(PRedisContext& pRD, const std::string& key, const uint32_t& offset, const uint32_t& limit, std::vector& datas); // (降序)从大到小获取指定段的数据, 0 score 不会被过滤掉
   bool getAscSortedData(PRedisContext& pRC, const string& key, const uint32_t& start, const uint32_t& end, std::vector &datas); // (升序)从小到大获取指定数据段的数据, 0 score 会被过滤掉
bool getAscSortedAllData(PRedisContext& pRD, const std::string& key, const uint32_t& start, const uint32_t& end, std::vector& datas); // (升序)从小到大获取指定数据段的数据, 0 score 不会被过滤掉
bool setSortedSet_T(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& score); // (事务)添加元素
bool decrScore_T(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& decrScore); // (事务)删除资源
bool incrMemScore_T(PRedisContext& pRD, const std::string& key, std::string& mem, const uint32_t& incrScore); // (事务)添加资源值


// --- Transaction(事务)
bool beginTransaction(PRedisContext& pRD);  // 开始事务,标记事务开始
bool endTransaction(PRedisContext& pRD, bool& isAborted);  // 结束事务,执行所有事务
bool endTransaction(PRedisContext& pRD, bool& isAborted, redisReply** pReply);  // 事务结束,执行所有事务 
bool discardTransaction(PRedisContext& pRD);  // 取消事务(回滚),取消执行模块内的所有事务
bool watch(PRedisContext& pRD, const std::string& key);  // 监控一个key
bool watch(PRedisContext& pRD, const vector& keys);  // 监控一些key
bool unwatch(PRedisContext& pRD);  // 取消监控key


// --- lua 脚本控制
bool loadScript(PRedisContext& pRD, const std::string& key,const std::string& script);// 加载脚本,指定脚本对应一个key
bool existsScript(PRedisContext& pRD, const std::string& key);  // 检查key指定的脚本是不是已经加载
bool getAllScriptKeys(PRedisContext& pRD);  // 获取已经加载的所有的脚本key
bool clearAllScript(PRedisContext& pRD);  // 清理所有已经加载的脚本缓存
bool exceScript(PRedisContext& pRD, const std::string& key, std::vector &outValue);  // 执行脚本,outValue表示返回数据
bool stopRuningScript(PRedisContext& pRD);  // 终止当前正在执行的脚本(且当该脚本没有执行写操作才能成功)


// -----------------reids执行报告----------------------
// 初始化redis执行报告; pid:为0表示监视所有线程,其他表示单一线程
uint32_t startRedisReport(uint32_t pid = 0);
void stopRedisReport();  // 关闭redis报告记录
std::string getRedisReport(); // 打印执行报告
void buildReport(std::string key, timeval startTime, timeval endTime); // 产生报告

private:
map > m_Script;  // 脚本
map m_allRedisConn; // 所有的redis连接
uint32_t m_MaxRedisContext;  // redis最大连接个数
RedisReport_t m_RedisReport;  // redis执行报告
ws::mutex m_RedisLock;  // 线程锁
private:
RedisManager() {};
};


#define REDIS_MANAGER RedisManager::Instence()


}


#endif /* REDIS_INTERFACE_H_ */
 

 

 

hiredis.c

redisConnectWithTimeout

redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {

    redisContext *c;

 

    c = redisContextInit();

    if (c == NULL)

        return NULL;

 

    c->flags |= REDIS_BLOCK;

    redisContextConnectTcp(c,ip,port,&tv);

    return c;

}

 

connect_redis_node

 

get_redis_node

 

redis_command

 

 

你可能感兴趣的:(Redis)