Выполнение команды HMSET с помощью hiredis

Я хочу поставить std::map<std::string, std::string> в сервер Redis с Hiredis. Поскольку API позволяет передавать только отформатированные строки redisCommandЯ не могу сохранить карту с помощью одной команды. Я пытался использовать конвейеры, но это медленнее, чем HMSET и, следовательно, не относится к ограничениям производительности, в которых я нахожусь.

Кто-нибудь знает о каких-либо прямых или косвенных методах передачи карты с измененным размером через hiredis?

2 ответа

Решение

Предполагается, что вы используете "Argv" разновидности redisCommand:

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.

Образец кода:

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

Проверьте документ для деталей.

Другие вопросы по тегам