- 依赖Redis官方提供的C库客户端hiredis
- 支持单主机(single node mode)与集群模式(cluster mode)
- 支持管道(pipeline)模式
- 使用连接池
- 线程安全
- 自动连接
- 不支持Windows
- 如果你要运行main.cpp执行测试用例,执行
mkdir build && cd build && cmake .. && make && ./redis-client
即可完成编译运行。 - 如果你要在
cpp-ethereum
项目中使用此功能。比如,你想在libjujsonrpc
中使用。那么请在libjujsonrpc
的CMakeLists.txt
中添加头文件target_include_directories(jujsonrpc PRIVATE ${HIREDIS_INCLUDE_DIR})
以及库文件target_link_libraries(jujsonrpc ${HIREDIS_LIBRARY})
。当然,有些可能因为他所包含的文件已经包含了该头文件与库,不需要添加。还有,不要忘记添加需要使用的头文件#include "libjuredisclient/RedisClient.h"
。需要注意的是,因为把Redis作为一项服务,所以已经在文件jueth/main.cpp
文件中已经调用了redis->Initialize("127.0.0.1", chainParams.m_redis_port, 2, 10)
从而执行Redis客户端连接服务端等一些初始化工作。所以你在其他地方再使用Redis做操作的时候,只需要使用代码CRedisClient::Instance()
获取一个指针实例之后就可以直接使用,不再需要执行初始化的工作。当然,如果你需要连接与默认不一样的Redis地址与端口,那么你需要使用CRedisClient()
构造一个实例,再用此实例进行初始化才能调用Redis的操作。 - 如果你需要使用 hiredis 库文件,库文件在
lib
目录下面。
#include <string>
#include "RedisClient.h"
int main(int argc, char **argv) {
CRedisClient* redisCli = CRedisClient::Instance();
if (!redisCli->Initialize("127.0.0.1", 6379, 2, 10))
{
std::cout << "connect to redis failed" << std::endl;
return -1;
}
std::string strKey = "name";
std::string strVal;
if (redisCli->Get(strKey, &strVal) == RC_SUCCESS)
{
std::cout << strKey << " has value " << strVal << std::endl;
return 0;
}
else
{
std::cout << "request failed" << std::endl;
return -1;
}
return 0;
}
更多测试用例,请看test目录。
- 实现
Scan
、Hscan
接口,也就意味着目前这两个接口不支持。
先说一下调用接口的一些返回值,在后面文档均用RequestRet描述。
Macro definition | Value | Description |
---|---|---|
RC_RESULT_EOF | 5 | 无结果再可取 |
RC_OBJ_NOT_EXIST | 3 | 对象不存在 |
RC_OBJ_EXIST | 2 | 对象存在 |
RC_PART_SUCCESS | 1 | 部分调用成功 |
RC_SUCCESS | 0 | 调用成功 |
RC_PARAM_ERR | -1 | 参数错误 |
RC_REPLY_ERR | -2 | 调用返回类型错误 |
RC_RQST_ERR | -3 | 重连失败 |
RC_NO_RESOURCE | -4 | 无连接 |
RC_PIPELINE_ERR | -5 | ppLine 传参错误 |
RC_NOT_SUPPORT | -6 | Redis不支持或未实现 |
static CRedisClient* Instance()
CRedisClient()
// nTimeout: 连接超时时间,单位秒。nConnNum:连接池数目
bool Initialize(const std::string &strHost, int nPort, int nTimeout, int nConnNum)
bool IsCluster()
Pipeline CreatePipeline()
int FlushPipeline(Pipeline ppLine)
int FetchReply(Pipeline ppLine, long *pnVal)
int FetchReply(Pipeline ppLine, std::string *pstrVal)
int FetchReply(Pipeline ppLine, std::vector<long> *pvecLongVal)
int FetchReply(Pipeline ppLine, std::vector<std::string> *pvecStrVal)
int FetchReply(Pipeline ppLine, redisReply **pReply)
void FreePipeline(Pipeline ppLine)
/* interfaces for generic */
Redis 键命令用于管理 redis 的键。
int Del(const std::string &strKey, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Dump(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
int Exists(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Expire(const std::string &strKey, long nSec, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Expireat(const std::string &strKey, long nTime, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Keys(const std::string &strPattern, std::vector<std::string> *pvecVal)
int Persist(const std::string &strKey, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Pexpire(const std::string &strKey, long nMilliSec, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Pexpireat(const std::string &strKey, long nMilliTime, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Pttl(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Randomkey(std::string *pstrVal, Pipeline ppLine = nullptr)
int Rename(const std::string &strKey, const std::string &strNewKey)
int Renamenx(const std::string &strKey, const std::string &strNewKey)
int Restore(const std::string &strKey, long nTtl, const std::string &strVal, Pipeline ppLine = nullptr)
int Scan(long *pnCursor, const std::string &strPattern, long nCount, std::vector<std::string> *pvecVal)
int Ttl(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Type(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
/* interfaces for string */
Redis 字符串数据类型的相关命令用于管理 redis 字符串值。
int Append(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Bitcount(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Bitcount(const std::string &strKey, long nStart, long nEnd, long *pnVal, Pipeline ppLine = nullptr)
int Bitop(const std::string &strDestKey, const std::string &strOp, const std::vector<std::string> &vecKey, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Bitpos(const std::string &strKey, long nBitVal, long *pnVal, Pipeline ppLine = nullptr)
int Bitpos(const std::string &strKey, long nBitVal, long nStart, long nEnd, long *pnVal, Pipeline ppLine = nullptr)
int Decr(const std::string &strKey, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Decrby(const std::string &strKey, long nDecr, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Get(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
int Getbit(const std::string &strKey, long nOffset, long *pnVal, Pipeline ppLine = nullptr)
int Getrange(const std::string &strKey, long nStart, long nEnd, std::string *pstrVal, Pipeline ppLine = nullptr)
int Getset(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
int Incr(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Incrby(const std::string &strKey, long nIncr, long *pnVal, Pipeline ppLine = nullptr)
int Incrbyfloat(const std::string &strKey, double dIncr, double *pdVal, Pipeline ppLine = nullptr)
int Mget(const std::vector<std::string> &vecKey, std::vector<std::string> *pvecVal)
int Mset(const std::vector<std::string> &vecKey, const std::vector<std::string> &vecVal)
int Psetex(const std::string &strKey, long nMilliSec, const std::string &strVal, Pipeline ppLine = nullptr)
int Set(const std::string &strKey, const std::string &strVal, Pipeline ppLine = nullptr)
int Setbit(const std::string &strKey, long nOffset, bool bVal, Pipeline ppLine = nullptr)
int Setex(const std::string &strKey, long nSec, const std::string &strVal, Pipeline ppLine = nullptr)
int Setnx(const std::string &strKey, const std::string &strVal, Pipeline ppLine = nullptr)
int Setrange(const std::string &strKey, long nOffset, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Strlen(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
/* interfaces for list */
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
一个列表最多可以包含2的32次方-1个元素(4294967295, 每个列表超过40亿个元素)。
int Blpop(const std::string &strKey, long nTimeout, std::vector<std::string> *pvecVal)
int Blpop(const std::vector<std::string> &vecKey, long nTimeout, std::vector<std::string> *pvecVal)
int Brpop(const std::string &strKey, long nTimeout, std::vector<std::string> *pvecVal)
int Brpop(const std::vector<std::string> &vecKey, long nTimeout, std::vector<std::string> *pvecVal)
int Lindex(const std::string &strKey, long nIndex, std::string *pstrVal, Pipeline ppLine = nullptr)
int Linsert(const std::string &strKey, const std::string &strPos, const std::string &strPivot, const std::string &strVal, long *pnVal, Pipeline ppLine = nullptr)
int Llen(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Lpop(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
int Lpush(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Lpush(const std::string &strKey, const std::vector<std::string> &vecVal, Pipeline ppLine = nullptr)
int Lpushx(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Lrange(const std::string &strKey, long nStart, long nStop, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Lrem(const std::string &strKey, long nCount, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Lset(const std::string &strKey, long nIndex, const std::string &strVal, Pipeline ppLine = nullptr)
int Ltrim(const std::string &strKey, long nStart, long nStop, Pipeline ppLine = nullptr)
int Rpop(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
int Rpush(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Rpush(const std::string &strKey, const std::vector<std::string> &vecVal, Pipeline ppLine = nullptr)
int Rpushx(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
/* interfaces for set */
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为2的32次方-1个元素(4294967295, 每个集合可存储40多亿个成员)。
int Sadd(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline = nullptr)
int Scard(const std::string &strKey, long *pnVal, Pipeline = nullptr)
int Sdiff(const std::vector<std::string> &vecKey, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr);
int Sinter(const std::vector<std::string> &vecKey, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr);
int Sismember(const std::string &strKey, const std::string &strVal, long *pnVal, Pipeline ppLine = nullptr)
int Smembers(const std::string &strKey, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Spop(const std::string &strKey, std::string *pstrVal, Pipeline ppLine = nullptr)
int Srandmember(const std::string &strKey, long nCount, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Srem(const std::string &strKey, const std::string &strVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Srem(const std::string &strKey, const std::vector<std::string> &vecVal, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Sunion(const std::vector<std::string> &vecKey, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr);
/* interfaces for hash */
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储2的32次方-1个键值对(40多亿)。
int Hdel(const std::string &strKey, const std::string &strField, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Hexists(const std::string &strKey, const std::string &strField, long *pnVal, Pipeline ppLine = nullptr)
int Hget(const std::string &strKey, const std::string &strField, std::string *pstrVal, Pipeline ppLine = nullptr)
int Hgetall(const std::string &strKey, std::map<std::string, std::string> *pmapFv, Pipeline ppLine = nullptr)
int Hincrby(const std::string &strKey, const std::string &strField, long nIncr, long *pnVal, Pipeline ppLine = nullptr)
int Hincrbyfloat(const std::string &strKey, const std::string &strField, double dIncr, double *pdVal, Pipeline ppLine = nullptr)
int Hkeys(const std::string &strKey, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Hlen(const std::string &strKey, long *pnVal, Pipeline ppLine = nullptr)
int Hmget(const std::string &strKey, const std::vector<std::string> &vecField, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Hmget(const std::string &strKey, const std::vector<std::string> &vecField, std::map<std::string, std::string> *pmapVal)
int Hmget(const std::string &strKey, const std::set<std::string> &setField, std::map<std::string, std::string> *pmapVal)
int Hmset(const std::string &strKey, const std::vector<std::string> &vecField, const std::vector<std::string> &vecVal, Pipeline ppLine = nullptr)
int Hmset(const std::string &strKey, const std::map<std::string, std::string> &mapFv, Pipeline ppLine = nullptr)
int Hscan(const std::string &strKey, long *pnCursor, const std::string &strMatch, long nCount, std::vector<std::string> *pvecVal);
int Hset(const std::string &strKey, const std::string &strField, const std::string &strVal, Pipeline ppLine = nullptr)
int Hsetnx(const std::string &strKey, const std::string &strField, const std::string &strVal, Pipeline ppLine = nullptr)
int Hvals(const std::string &strKey, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
/* interfaces for sorted set */
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为2的32次方-1个(4294967295, 每个集合可存储40多亿个成员)。
int Zadd(const std::string &strKey, double dScore, const std::string &strElem, long *pnVal = nullptr, Pipeline = nullptr)
int Zcard(const std::string &strKey, long *pnVal, Pipeline = nullptr)
int Zcount(const std::string &strKey, double dMin, double dMax, long *pnVal, Pipeline ppLine = nullptr)
int Zincrby(const std::string &strKey, double dIncr, const std::string &strElem, double *pdVal, Pipeline ppLine = nullptr)
int Zlexcount(const std::string &strKey, const std::string &strMin, const std::string &strMax, long *pnVal, Pipeline ppLine = nullptr)
int Zrange(const std::string &strKey, long nStart, long nStop, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Zrangewithscore(const std::string &strKey, long nStart, long nStop, std::map<std::string, std::string> *pmapVal, Pipeline ppLine = nullptr)
int Zrangebylex(const std::string &strKey, const std::string &strMin, const std::string &strMax, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Zrangebyscore(const std::string &strKey, double dMin, double dMax, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Zrangebyscore(const std::string &strKey, double dMin, double dMax, std::map<std::string, double> *pmapVal, Pipeline ppLine = nullptr)
int Zrank(const std::string &strKey, const std::string &strElem, long *pnVal, Pipeline ppLine = nullptr)
int Zrem(const std::string &strKey, const std::string &strElem, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Zrem(const std::string &strKey, const std::vector<std::string> &vecElem, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Zremrangebylex(const std::string &strKey, const std::string &strMin, const std::string &strMax, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Zremrangebyrank(const std::string &strKey, long nStart, long nStop, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Zremrangebyscore(const std::string &strKey, double dMin, double dMax, long *pnVal = nullptr, Pipeline ppLine = nullptr)
int Zrevrange(const std::string &strKey, long nStart, long nStop, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Zrevrangebyscore(const std::string &strKey, double dMax, double dMin, std::vector<std::string> *pvecVal, Pipeline ppLine = nullptr)
int Zrevrangebyscore(const std::string &strKey, double dMax, double dMin, std::map<std::string, double> *pmapVal, Pipeline ppLine = nullptr)
int Zrevrank(const std::string &strKey, const std::string &strElem, long *pnVal, Pipeline ppLine = nullptr)
int Zscore(const std::string &strKey, const std::string &strElem, double *pdVal, Pipeline ppLine = nullptr)
/* interfaces for system */
Redis 服务器命令主要是用于管理 redis 服务(只实现一个)。
int Time(struct timeval *ptmVal, Pipeline ppLine = nullptr)
获取单例指针。
构造函数,构造一个CRedisClient对象。
初始化链接。strHost:服务器IP。nPort:服务器端口。nTimeout: 连接超时时间,单位秒。nConnNum:连接池数目
删除键。strKey:键。pnVal:被删除键的个数。ppLine:管道。
序列化给定 key ,并返回被序列化的值。strKey:键。pstrVal:序列化后的值。ppLine:管道。
key是否存在。strKey:键。pnVal:若为1则key存在,为0则不存在。ppLine:管道。
设置key的过期时间,超过时间后,将会自动删除该key。strKey:键。nSec:过期时间,单位秒。pnVal:1 如果成功设置过期时间,0 如果key不存在或者不能设置过期时间。ppLine:管道。
int Expireat(const std::string &strKey, long nTime, long *pnVal = nullptr, Pipeline ppLine = nullptr)
设置key的过期时间,超过时间后,将会自动删除该key。参考Expire,不同的是命令接受的时间参数是 UNIX 时间戳 Unix timestamp。
查找所有符合给定模式pattern(正则表达式)的 key。strPattern:键的正则表达模式。pvecVal:所有符合条件的key。
移除给定key的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。strKey:键。pnVal:当生存时间移除成功时,返回 1。如果 key 不存在或 key 没有设置生存时间,返回 0 。ppLine:管道。
int Pexpire(const std::string &strKey, long nMilliSec, long *pnVal = nullptr, Pipeline ppLine = nullptr)
设置key的过期时间,超过时间后,将会自动删除该key。参考Expire,不同的是它以毫秒为单位设置 key 的生存时间。
int Pexpireat(const std::string &strKey, long nMilliTime, long *pnVal = nullptr, Pipeline ppLine = nullptr)
设置key的过期时间,超过时间后,将会自动删除该key。参考Pexpire,不同的是它以毫秒为单位设置 key 的过期 UNIX 时间戳。
以毫秒为单位返回 key 的剩余生存时间。strKey:键。pnVal:如果key不存在返回-2,如果key存在且无过期时间返回-1 。ppLine:管道。
以毫秒为单位返回 key 的剩余生存时间。strKey:键。pnVal:如果key不存在返回-2,如果key存在且无过期时间返回-1 。ppLine:管道。
从当前数据库返回一个随机的key。pstrVal:返回的键值。ppLine:管道。
将key重命名为newkey,如果key与newkey相同,将返回一个错误RC_REPLY_ERR。如果newkey已经存在,则值将被覆盖。strKey:旧键值。strNewKey:新键值。
当且仅当 newkey 不存在时,将 key 改名为 newkey。strKey:旧键值。strNewKey:新键值。如果修改失败(如当 key 不存在时, newKey已存在),返回RC_REPLY_ERR。
int Restore(const std::string &strKey, long nTtl, const std::string &strVal, Pipeline ppLine = nullptr)
反序列化给定的序列化值,并将它和给定的 key 关联。strKey:旧键值。nTtl:毫秒为单位为 key 设置生存时间。ppLine:管道。
int Scan(long *pnCursor, const std::string &strPattern, long nCount, std::vector<std::string> *pvecVal)
迭代当前数据库中的key集合。pnCursor:游标。strPattern:正则表达式。nCount:数量。pvecVal:值。
以秒为单位返回 key 的剩余生存时间。strKey:键。pnVal:如果key不存在返回-2,如果key存在且无过期时间返回-1 。ppLine:管道。
返回key所存储的value的数据结构类型,它可以返回string, list, set, zset 和 hash等不同的类型。strKey:键。pstrVal:类型,不存在返回none。ppLine:管道。