Giter VIP home page Giter VIP logo

r3c's Introduction

Redis Cluster C++ Client, based on hiredis, support password and standalone, it's easy to make and use, not depends on C++11 or later. r3c::CRedisClient is not thread safe, you can use __thread to create a object of r3c::CRedisClient for every thread.

r3c基于redis官方的c库hiredis实现,全称是redis cluster C++ client,支持redis cluster,支持密码访问。 非线程安全,GCC环境可以使用__thread为每个线程创建一个r3c::CRedisClient实例。 支持多种策略的从读,支持Redis-5.0新增的Stream操作。不支持异步,但可结合协程实现异步访问,可参照示例r3c_and_coroutine.cpp。

编译链接r3c时,默认认为hiredis的安装目录为/usr/local/hiredis, 但可以在执行make时指定hiredis安装目录,如假设hiredis安装目录为/tmp/hiredis:make HIREDIS=/tmp/hiredis, 或修改Makefile中变量HIREDIS的值来指定hiredis实现的安装目录。

编译r3c成功后,将生成libr3c.a静态库,没有共享库被生成。 也可以直接将r3c.h、r3c.cpp、utils.h、utils.cpp、sha1.h和sha1.cpp几个文件加入到自己项目代码中一起编译,而不独立编译r3c。


r3c_cmd.cpp是r3c的非交互式命令行工具(command line tool),具备redis-cli的一些功能,但用法不尽相同,将逐步将覆盖redis-cli的所有功能。 r3c_test.cpp是r3c的单元测试程序(unit test),执行make test即可。 r3c_and_coroutine.cpp 在协程中使用r3c示例(异步)


支持两种编译和安装方式(make&cmake):
1) make
编译:
make

安装(PREFIX指定安装目录,如果不指定则为/usr/local):
make install

make install PREFIX=/usr/local/r3c

执行单元测试:
make test

make test REDIS_CLUSTER_NODES=192.168.1.31:6379,192.168.1.31:6380

2) cmake
生成Makefile文件:
cmake -DCMAKE_INSTALL_PREFIX=install-directory .
示例:
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/r3c .

编译:
make

安装:
make install


关于接口:
如果传给CRedisClient的nodes参数为单个节点字符串,如192.168.1.31:6379则为单机模式,为多节点字符串时则为Redis Cluster模式。


性能测试工具:
https://github.com/eyjian/libmooon/blob/master/tools/r3c_stress.cpp

单机性能数据:
r3c_stress --redis=192.168.0.88:6379 --requests=100000 --threads=20 set: microseconds=18867143, milliseconds=18867, seconds=18 total: 2000000, success: 2000000, failure: 0 qps: 111111

get: microseconds=16063882, milliseconds=16063, seconds=16 total: 2000000, success: 2000000, failure: 0, not exists: 0 qps: 125000

hset: microseconds=16134011, milliseconds=16134, seconds=16 total: 1999992, success: 1999992, failure: 0 qps: 124999

hget: microseconds=15249201, milliseconds=15249, seconds=15 total: 2000000, success: 2000000, failure: 0, not exists: 0 qps: 133333

r3c's People

Contributors

eyjian avatar jzh800 avatar raymonzhong avatar sekarpdkt avatar tianxingpan avatar wnsmjun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

r3c's Issues

C++17 support and some issue in make

hi

  1. Will you be able to support C++17. Primarily dynamic exception specifications like throw (CRedisException); are no more supported.

  2. When I do make,

/usr/bin/c++  -g  -rdynamic CMakeFiles/r3c_test.dir/r3c_test.cpp.o  -o r3c_test  -L/r3c  -L/r3c/HIREDIS_LIB-NOTFOUND -Wl,-rpath,/r3c:/r3c/HIREDIS_LIB-NOTFOUND -Wl,-Bstatic -lr3c -lhiredis -Wl,-Bdynamic

fails with error /usr/bin/ld: cannot find -lhiredis

If I remove extra -Wl, before -Bstatic, it works. Mean

/usr/bin/c++  -g  -rdynamic CMakeFiles/r3c_test.dir/r3c_test.cpp.o  -o r3c_test  -L/r3c  -L/r3c/HIREDIS_LIB-NOTFOUND -Wl,-rpath,/r3c:/r3c/HIREDIS_LIB-NOTFOUND  -Bstatic -lr3c -lhiredis -Wl,-Bdynamic

works.

LPop返回超时

bool CRedisClient::lpop(const std::string& key, std::string* value, Node* which, int num_retries)
{
    CommandArgs cmd_args;
    cmd_args.set_key(key);
    cmd_args.set_command("LPOP");
    cmd_args.add_arg(cmd_args.get_command());
    cmd_args.add_arg(key);
    cmd_args.final();

    // Bulk string reply: the value of the first element, or nil when key does not exist.
    const RedisReplyHelper redis_reply = redis_command(false, num_retries, key, cmd_args, which);
    if (REDIS_REPLY_NIL == redis_reply->type)
        return false;
    if (REDIS_REPLY_STRING == redis_reply->type)
        return get_value(redis_reply.get(), value);
    return true; // MULTI & EXEC the type always is REDIS_REPLY_STATUS
}

redis_command第一个参数is_read_command被设为false,导致异步模式下redisReply直接被丢弃

about hset return value

else if (REDIS_REPLY_INTEGER == redis_reply->type)
{
result = redis_reply->integer;
}

bool CRedisClient::hset(const std::string& key, const std::string& field, const std::string& value, std::pair<std::string, uint16_t>* which) throw (CRedisException)
{
struct ParamInfo param_info("HSET", sizeof("HSET")-1, &key, which);
param_info.str1 = &field;
param_info.str2 = &value;
int64_t result = redis_command(REDIS_REPLY_INTEGER, &param_info);
return result > 0;
}

When the value set by hset is written repeatedly, redis_reply-> integer returns the value 0.
so hset will return false.

当hset重复存入的value时, redis_reply-> integer 返回值是0。
会导致hset 函数中 关于 大于0的判断 返回 false。 这里是不是应该改为 >=0 ,或者 修改为 返回int类型

Typo in rpush function

Typo in rpush function

---a/r3c.cpp
+++ b/r3c.cpp
@@ -880,7 +880,7 @@ bool CRedisClient::rpop(const std::string& key, std::string* value, std::pair<st
 int CRedisClient::rpush(const std::string& key, const std::string& value, std::pair<std::string, uint16_t>* which) throw (CRedisException)
 {
     std::vector<std::string> values(1, value);
-    return rpush(key, value, which);
+    return rpush(key, values, which);
 }

EVAL. How to use it

Following code, always returns 1. What can be the issue?

        const std::string& lua_scripts = r3c::format_string("local i=0; redis.call('HINCRBY',KEYS[1],ARGV[1],1); i= redis.call('HGET',KEYS[1],ARGV[1]); return i;");
        std::vector<std::string> keys;
        std::vector<std::string> parameters;
        parameters.push_back("MYINSTANCE");
        keys.push_back("NEXTINSTANCEID");
        unsigned int myIDi=1;
        const r3c::RedisReplyHelper redis_reply = rc.eval(lua_scripts,keys,parameters);
        
        if (REDIS_REPLY_INTEGER == redis_reply->type)
            myIDi= static_cast<int>(redis_reply->integer);

        std::cout << myIDi << std::endl;

If I execute same in redis_cli, it works.

192.168.1.12:7050> eval "local i=0; redis.call('HINCRBY',KEYS[1],ARGV[1],1); i= redis.call('HGET',KEYS[1],ARGV[1]); return i;" 1 NEXTINSTANCEID MYINSTANCE
"16"

json 存储到redis hash格式问题?

使用R3C存储 json 字符串
nlohmann::json j;
j["file"] = "demo.mp3";
std::string val = j.dump();
std::cout<<"json string "<<val<<std::endl;
if (!rc.hset("domain/f", "domain", val))

存储格式为
{"file":"demo.mp3"},
使用R3C 读取的字符串没有问题,

但是实验redis客户端读取出来,多一个反斜杠,hget domain/f domain
"{"file":"demo.mp3"}"
这个编辑器好像去掉了,附上一张图片。

使用nginx, lua客户端端读取也是带反斜杠的。
有没有简单的解决思路?

[bug] 集群模式下循环尝试链接时,connect_redis_node 传进去的errorinfo没有清空

场景描述:
集群模式下,设置密码。如果一个主节点异常,从节点转换为主节点。
调用构造函数时,节点信息传入的是原始的主节点信息。
此时循环尝试连接节点时,如果第一次连接到坏掉的节点,连接的异常信息会保存在errorinfo里面。

在第二次连接时,errorinfo信息被传入connect_redis_node()。上次失败的errorinfo信息没有被清空,会影响本次连接时的AUTH验证。 触发 NOAUTH Authentication required 的异常。

在 r3c.cpp 中 zrangebyscore 的实现 min 和 max 值的传递弄反了。

在 1670 行 : CRedisClient::zrangebyscore 的实现中,
应该修改 const std::string str1 = any2string(min); const std::string str2 = any2string(max);

在 1692 行 : CRedisClient::zrevrangebyscore 的实现中,
应该修改 const std::string str1 = any2string(min); const std::string str2 = any2string(max);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.