Node-redis: Pipelining

Criado em 13 jan. 2014  ·  9Comentários  ·  Fonte: NodeRedis/node-redis

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

Feature Request fixed / done

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:

  1. O retorno de chamada para o sismember é o que invoca a chamada hgetall - portanto, você está impedindo implicitamente que esses comandos sejam canalizados juntos para qualquer chamada sismember. O retorno de chamada não é invocado até que o Redis responda.
  2. Se 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

Todos 9 comentários

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,

  1. Estou confuso, qual é o propósito de "multi" funções dentro de node_redis então?
  2. Qual é o algoritmo usado para pipeline automaticamente os comandos?

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:

  1. O retorno de chamada para o sismember é o que invoca a chamada hgetall - portanto, você está impedindo implicitamente que esses comandos sejam canalizados juntos para qualquer chamada sismember. O retorno de chamada não é invocado até que o Redis responda.
  2. Se 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.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

jackycchen picture jackycchen  ·  4Comentários

Stono picture Stono  ·  6Comentários

strumwolf picture strumwolf  ·  4Comentários

dotSlashLu picture dotSlashLu  ·  5Comentários

Alchemystic picture Alchemystic  ·  6Comentários