4

我想std::map<std::string, std::string>用hiredis放入redis服务器。由于API 只允许将格式化字符串传递给redisCommand,因此我无法通过单个命令存储地图。我尝试过使用管道,但这比我所在的性能限制要慢HMSET,因此不适用于我所在的性能限制。

任何人都知道通过hiredis传递变体大小的地图的任何直接或间接方法吗?

4

2 回答 2

4

您应该使用 redisCommand 的“Argv”风格:

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 是单线程的。当执行一个巨大的命令时,不会执行其他任何操作。另外,您可以达到通信缓冲区的限制。

于 2015-08-16T08:11:55.427 回答
3

这是一个较晚的答案,但是,使用redis-plus-plus,您可以轻松地将 astd::map<std::string, std::string>放入 Redis。

免责声明:我是这个 Redis 客户端库的作者。如果您对此客户有任何问题,请随时告诉我。如果你喜欢它,也可以随意给它加星:)

示例代码:

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());

检查文档以获取详细信息。

于 2018-11-30T05:18:58.310 回答