Привет, народ,
как программно включить конвейерную обработку в node_redis?
Я видел документацию, в которой говорится, что в большинстве случаев это происходит автоматически, и я хочу понять, есть ли способ принудительно принудительно использовать это из кода приложения в node_redis
[ ec2-user @ DevOps ~] $ redis-benchmark -n 100000 -t set, получить -P 16 -q -h 10.0.1.10
НАБОР: 199600.80 запросов в секунду
GET: 193050,19 запросов в секунду
[ ec2-user @ DevOps ~] $ redis-benchmark -n 100000 -t set, получить -q -h 10.0.1.12
НАБОР: 14098,41 запросов в секунду
GET: 13743,82 запроса в секунду
на узле Redis разница более чем в 10 раз.
Благодарность,
Дмитрий
Это делается с помощью команд client.multi и multi.exec?
Привет @saritasa - конвейерная обработка автоматическая. Это всегда происходит внутри клиента. Вам не нужно использовать multi или exec, чтобы включить его.
Привет Брайс,
Благодарность,
Дмитрий
Множественные операции взяты из спецификации протокола Redis, они имеют транзакционную цель за пределами конвейерной обработки: http://redis.io/commands/multi
С точки зрения того, как работает конвейерная обработка: http://redis.io/topics/pipelining, это просто вопрос того, что клиент пишет команды в Redis так же быстро, как вы их отправляете, не дожидаясь ответа, прежде чем писать следующую. Клиент отслеживает отправленные команды, а затем совмещает ответы с отправленными командами после ответа Redis.
Спасибо, Брайс, я понимаю, как работает http://redis.io/topics/pipelining . в приложении node.js - как должен быть структурирован код, чтобы запросы были конвейерными?
так что в примере ниже
hgetall & expire - конвейерные или нет? Один из вызовов - внутренний обратный вызов.
function getByID (table, id, next) {
если (! успех) return setTimeout (function () {
getByID (таблица, идентификатор, следующий);
}, 2000);
var end = utils.getEndTime(),
base = getBase(),
client = getClient(PK2str(table, id)),
key = getHashID(table, id);
base.sismember(table, key, function (err, val) {
if (err || !val) return next();
client.hgetall(key, function (err, val) {
if (err || !val) return next(new Error('Expired'), id);
val = arrays_parse(table, val);
next(null, val);
client.expire(key, cfg.ttl.shards);
if (!exports.silent) {
profiler.log('cache', {
'table': table,
'id': key,
'method': 'getByID',
'data': val,
'time': end()
});
}
});
});
}
Все команды отправляются «конвейерно», но они никогда не будут отправлены в одном кадре записи конвейера по одной или двум причинам:
base
и client
- разные клиенты Redis, они НИКОГДА не могут использовать один и тот же конвейер.Команды должны выполняться из одного и того же контекста *, чтобы увидеть какие-либо преимущества конвейерной обработки. Например, аналогично примеру PING в документации по конвейерной обработке Redis:
// These commands will all be pipelined together:
client.ping()
client.ping()
client.ping()
client.ping(function () {
// This would *NEVER* be in the same pipeline frame as the other four because it requires a reply to be received first
client.ping()
})
* или из разных контекстов, если отправлено быстрее, чем Redis отвечает, но никогда не отвечает в зависимых контекстах
получил сейчас - спасибо! Это очень ценный комментарий!
Я думаю, что node_redis «автоматическая конвейерная обработка» - это не конвейерная обработка, на которую ссылается официальный redis.
Это время называется RTT (время туда и обратно). Очень легко увидеть, как это может повлиять на производительность, когда клиенту необходимо выполнить множество запросов подряд (например, добавить много элементов в один и тот же список или заполнить базу данных множеством ключей). Например, если время RTT составляет 250 миллисекунд (в случае очень медленного соединения через Интернет), даже если сервер способен обрабатывать 100 тысяч запросов в секунду, мы сможем обрабатывать максимум четыре запроса в секунду.
Если используемый интерфейс является интерфейсом с обратной связью, RTT намного короче (например, мой хост сообщает о 0,044 миллисекундах пинг 127.0.0.1), но это все равно много, если вам нужно выполнить много записей подряд.
Конвейерная обработка с помощью официального redis означает объединение нескольких команд и их однократную отправку для противодействия задержке из-за RTT, которая не обрабатывается node_redis. А «автоматическая конвейерная обработка» в node_redis фактически отправляет как можно больше команд одновременно с использованием модели асинхронного программирования Node.
Вот хорошая статья, в которой обсуждается этот вопрос. http://informatikr.com/2012/redis-pipelining.html
@Vizwind @saritasa и .multi, и .batch используют конвейерную обработку, как это предполагалось начиная с версии 2.2.
Самый полезный комментарий
Все команды отправляются «конвейерно», но они никогда не будут отправлены в одном кадре записи конвейера по одной или двум причинам:
base
иclient
- разные клиенты Redis, они НИКОГДА не могут использовать один и тот же конвейер.Команды должны выполняться из одного и того же контекста *, чтобы увидеть какие-либо преимущества конвейерной обработки. Например, аналогично примеру PING в документации по конвейерной обработке Redis:
* или из разных контекстов, если отправлено быстрее, чем Redis отвечает, но никогда не отвечает в зависимых контекстах