Oi, pessoal,
como habilitar pipelining em node_redis programaticamente?
Eu vi a documentação dizendo que isso acontece automaticamente na maioria dos casos - e quero entender se há uma maneira de forçar isso do código do aplicativo programaticamente em node_redis
[ ec2-user @ devops ~] $ redis-benchmark -n 100000 -t set, get -P 16 -q -h 10.0.1.10
SET: 199600,80 solicitações por segundo
GET: 193050,19 solicitações por segundo
[ ec2-user @ devops ~] $ redis-benchmark -n 100000 -t set, get -q -h 10.0.1.12
SET: 14098,41 solicitações por segundo
GET: 13743,82 solicitações por segundo
é mais de 10 vezes a diferença no nó Redis.
obrigado,
Dmitry
Isso é feito por meio dos comandos client.multi e multi.exec?
Olá @saritasa - o pipelining é automático. Está sempre acontecendo dentro do cliente. Você não precisa usar multi ou exec para habilitá-lo.
Oi Bryce,
obrigado,
Dmitry
As operações múltiplas são da especificação do protocolo Redis e têm um propósito transacional fora do pipelining: http://redis.io/commands/multi
Em termos de como o pipelining funciona: http://redis.io/topics/pipelining, isso é apenas uma questão de o cliente escrever comandos para o Redis tão rápido quanto você os envia, sem esperar pela resposta antes de escrever o próximo. O cliente controla os comandos enviados e, em seguida, realinha as respostas com os comandos enviados assim que o Redis responder.
Obrigado Bryce, eu entendo como funciona http://redis.io/topics/pipelining . em um aplicativo node.js - como o código deve ser estruturado para que as solicitações sejam encaminhadas?
então no exemplo abaixo
hgetall & expire - são pipeline ou não? Uma das chamadas é um retorno de chamada interno.
function getByID (table, id, next) {
if (! sucesso) return setTimeout (function () {
getByID (tabela, id, próximo);
}, 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()
});
}
});
});
}
Todos os comandos são enviados "em pipeline", mas nunca seriam enviados no mesmo quadro de gravação de pipeline por um ou dois motivos:
base
e client
forem clientes Redis diferentes, eles podem _NEVER_ compartilhar o mesmo pipeline.Os comandos precisam ser executados no mesmo contexto * para ver qualquer benefício do pipelining. Por exemplo, semelhante ao exemplo PING nos documentos de pipelining 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()
})
* ou de contextos separados se enviado mais rápido do que o Redis está respondendo, mas nunca responda em contextos dependentes
entendi agora - obrigado! Este é um comentário muito valioso!
Acho que node_redis "pipelining automático" não é o pipelining referido pelo redis oficial.
Este tempo é denominado RTT (Round Trip Time). É muito fácil ver como isso pode afetar o desempenho quando um cliente precisa realizar muitas solicitações em uma linha (por exemplo, adicionar muitos elementos à mesma lista ou preencher um banco de dados com muitas chaves). Por exemplo, se o tempo de RTT for 250 milissegundos (no caso de um link muito lento pela Internet), mesmo se o servidor for capaz de processar 100 mil solicitações por segundo, seremos capazes de processar no máximo quatro solicitações por segundo.
Se a interface usada for uma interface de loopback, o RTT é muito mais curto (por exemplo, meu host reporta 0,044 milissegundos de ping 127.0.0.1), mas ainda é muito se você precisar realizar muitas gravações em uma linha.
O que o pipelining pelo redis oficial significa é combinar vários comandos e enviá-los uma vez para conter a latência devida ao RTT, que não é endereçada pelo node_redis. E "automatica pipelining" em node_redis está realmente enviando tantos comandos quanto possível ao mesmo tempo usando o modelo de programação assíncrona do Node.
Aqui está um bom artigo discutindo esse assunto. http://informatikr.com/2012/redis-pipelining.html
@Vizwind @saritasa .multi e .batch usam pipelining como pensado a partir da versão 2.2.
Comentários muito úteis
Todos os comandos são enviados "em pipeline", mas nunca seriam enviados no mesmo quadro de gravação de pipeline por um ou dois motivos:
base
eclient
forem clientes Redis diferentes, eles podem _NEVER_ compartilhar o mesmo pipeline.Os comandos precisam ser executados no mesmo contexto * para ver qualquer benefício do pipelining. Por exemplo, semelhante ao exemplo PING nos documentos de pipelining redis:
* ou de contextos separados se enviado mais rápido do que o Redis está respondendo, mas nunca responda em contextos dependentes