Может ли Redis отключить ответы для конвейерных команд?

В настоящее время я разрабатываю кеш, который требует увеличения нескольких сотен счетчиков для каждого такого вызова:

redis.pipelined do
  keys.each{ |key| redis.incr key }
end

В своем профилировании я увидел, что ответы, которые мне не нужны, по-прежнему собираются драгоценным камнем Redis и тратят впустую некоторое драгоценное время. Могу ли я каким-то образом сказать Redis, что меня не интересуют ответы? Есть ли лучший способ увеличить множество значений.

Например, я не нашел команду MINCR..

Заранее спасибо!


person Thomas Fankhauser    schedule 23.10.2012    source источник


Ответы (3)


Да... в 2.6, по крайней мере. Вы можете сделать это в сценарии LUA, и просто сценарий LUA вернет пустой результат. Здесь используется клиент bookleeve:

const int DB = 0; // any database number
// prime some initial values
conn.Keys.Remove(DB, new[] {"a", "b", "c"});
conn.Strings.Increment(DB, "b");
conn.Strings.Increment(DB, "c");
conn.Strings.Increment(DB, "c");

// run the script, passing "a", "b", "c", "c" to
// increment a & b by 1, c twice
var result = conn.Scripting.Eval(DB,
    @"for i,key in ipairs(KEYS) do redis.call('incr', key) end",
    new[] { "a", "b", "c", "c"}, // <== aka "KEYS" in the script
    null); // <== aka "ARGV" in the script

// check the incremented values
var a = conn.Strings.GetInt64(DB, "a");
var b = conn.Strings.GetInt64(DB, "b");
var c = conn.Strings.GetInt64(DB, "c");

Assert.IsNull(conn.Wait(result), "result");
Assert.AreEqual(1, conn.Wait(a), "a");
Assert.AreEqual(2, conn.Wait(b), "b");
Assert.AreEqual(4, conn.Wait(c), "c");

Или, чтобы сделать то же самое с incrby, передав числа "by" в качестве аргументов, измените среднюю часть на:

// run the script, passing "a", "b", "c" and 1, 1, 2
// increment a & b by 1, c twice
var result = conn.Scripting.Eval(DB,
    @"for i,key in ipairs(KEYS) do redis.call('incrby', key, ARGV[i]) end",
    new[] { "a", "b", "c" }, // <== aka "KEYS" in the script
    new object[] { 1, 1, 2 }); // <== aka "ARGV" in the script
person Marc Gravell    schedule 23.10.2012
comment
Замечательно! Полностью упустил из виду подход к написанию сценариев. Большое спасибо! - person Thomas Fankhauser; 29.10.2012

Нет, это невозможно. Невозможно сказать Redis не отвечать.

Единственный способ избежать синхронного ожидания ответов в некоторых моментах — запустить полностью асинхронный клиент (например, node.js или наемный клиент в асинхронном режиме).

person Didier Spezia    schedule 23.10.2012
comment
Это очень возможно... в 2.6 - person Marc Gravell; 23.10.2012

Версия 3.2 Redis явно поддерживает это:

https://redis.io/commands/client-reply

Команда CLIENT REPLY определяет, будет ли сервер отвечать на команды клиента. Доступны следующие режимы: ВКЛ. Это режим по умолчанию, в котором сервер возвращает ответ на каждую команду. ВЫКЛЮЧЕННЫЙ. В этом режиме сервер не будет отвечать на команды клиента. ПРОПУСКАТЬ. Этот режим пропускает ответ команды сразу после нее.

Возвращаемое значение При вызове с подкомандами OFF или SKIP ответ не выдается. При вызове с ON: Простой строковый ответ: OK.

person James    schedule 12.01.2018
comment
Как эту команду можно запустить вне интерфейса командной строки Redis? Есть ли библиотека, которая это реализует? - person SeanO; 26.04.2018
comment
@SeanO Я не уверен, достаточно ли интеллектуальна библиотека наемных работ, чтобы не ждать ответа, если приведенная выше команда предшествует реальной команде. - person James; 26.04.2018