使用 hiredis 执行 HMSET 命令
Executing HMSET command with hiredis
我想用 hiredis 将 std::map<std::string, std::string>
放入 redis 服务器。由于要将 API only allows formatted strings 传递给 redisCommand
,我无法通过单个命令存储地图。我试过使用管道,但这比 HMSET
慢,因此不适用于我所处的性能限制。
有人知道通过 hiredis 传递不同大小的地图的任何直接或间接方法吗?
您应该使用 "Argv" 风格的 redis 命令:
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
您需要构建两个数组(指针和大小)才能调用它们。
像这样的东西应该可以工作(未经测试):
void hmset( redisContext *c, const string &key, const map<string,string> &m )
{
vector<const char *> argv;
vector<size_t> argvlen;
static char cmd[] = "HMSET";
argv.push_back( cmd );
argvlen.push_back( sizeof(cmd)-1 );
argv.push_back( key.c_str() );
argvlen.push_back( key.size() );
map<string,string>::const_iterator i;
for ( i=m.begin(); i!=m.end(); ++i )
{
argv.push_back( i->first.c_str() );
argvlen.push_back( i->first.size() );
argv.push_back( i->second.c_str() );
argvlen.push_back( i->second.size() );
}
void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
if ( !r )
throw runtime_error( "Redis error" );
freeReplyObject( r );
}
请注意,如果您的地图包含很多项目,则通过一个命令将其推送到 Redis 是错误的想法。过去 N=100-1000 项,可变参数命令应该被拆分(以 N 项为一组)并流水线化。请记住,Redis 是单线程的。当执行一个巨大的命令时,不会执行任何其他命令。另外,您可以达到通信缓冲区的限制。
这是一个迟到的答案,但是,使用 redis-plus-plus 您可以轻松地将 std::map<std::string, std::string>
放入 Redis。
免责声明:我是这个 Redis 客户端库的作者。如果您对此客户端有任何问题,请随时 let me know. If you like it, also feel free to star it :)
示例代码:
Redis redis("tcp://127.0.0.1:6379");
std::map<std::string, std::string> m = {std::make_pair("k1", "v1"), std::make_pair("k2", "v2")};
redis.hmset("hash-key", m.begin(), m.end());
查看文档了解详细信息。
我想用 hiredis 将 std::map<std::string, std::string>
放入 redis 服务器。由于要将 API only allows formatted strings 传递给 redisCommand
,我无法通过单个命令存储地图。我试过使用管道,但这比 HMSET
慢,因此不适用于我所处的性能限制。
有人知道通过 hiredis 传递不同大小的地图的任何直接或间接方法吗?
您应该使用 "Argv" 风格的 redis 命令:
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
您需要构建两个数组(指针和大小)才能调用它们。
像这样的东西应该可以工作(未经测试):
void hmset( redisContext *c, const string &key, const map<string,string> &m )
{
vector<const char *> argv;
vector<size_t> argvlen;
static char cmd[] = "HMSET";
argv.push_back( cmd );
argvlen.push_back( sizeof(cmd)-1 );
argv.push_back( key.c_str() );
argvlen.push_back( key.size() );
map<string,string>::const_iterator i;
for ( i=m.begin(); i!=m.end(); ++i )
{
argv.push_back( i->first.c_str() );
argvlen.push_back( i->first.size() );
argv.push_back( i->second.c_str() );
argvlen.push_back( i->second.size() );
}
void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
if ( !r )
throw runtime_error( "Redis error" );
freeReplyObject( r );
}
请注意,如果您的地图包含很多项目,则通过一个命令将其推送到 Redis 是错误的想法。过去 N=100-1000 项,可变参数命令应该被拆分(以 N 项为一组)并流水线化。请记住,Redis 是单线程的。当执行一个巨大的命令时,不会执行任何其他命令。另外,您可以达到通信缓冲区的限制。
这是一个迟到的答案,但是,使用 redis-plus-plus 您可以轻松地将 std::map<std::string, std::string>
放入 Redis。
免责声明:我是这个 Redis 客户端库的作者。如果您对此客户端有任何问题,请随时 let me know. If you like it, also feel free to star it :)
示例代码:
Redis redis("tcp://127.0.0.1:6379");
std::map<std::string, std::string> m = {std::make_pair("k1", "v1"), std::make_pair("k2", "v2")};
redis.hmset("hash-key", m.begin(), m.end());
查看文档了解详细信息。