Node-redis: Canalización

Creado en 13 ene. 2014  ·  9Comentarios  ·  Fuente: NodeRedis/node-redis

Hola tios,

¿Cómo habilitar la canalización en node_redis programáticamente?

Vi que la documentación dice que sucede automáticamente en la mayoría de los casos, y quiero entender si hay alguna manera de forzarlo desde el código de la aplicación mediante programación en node_redis

[ ec2-user @ devops ~] $ redis-benchmark -n 100000 -t set, get -P 16 -q -h 10.0.1.10
SET: 199600.80 solicitudes por segundo
OBTENER: 193050,19 solicitudes por segundo

[ ec2-user @ devops ~] $ redis-benchmark -n 100000 -t set, get -q -h 10.0.1.12
SET: 14098.41 solicitudes por segundo
OBTENER: 13743.82 solicitudes por segundo

es más de 10 veces la diferencia en el nodo de Redis.

Gracias,
Dmitry

Feature Request fixed / done

Comentario más útil

Todos los comandos se envían "en canalización", pero estos nunca se enviarían en el mismo marco de escritura de canalización por una o dos razones:

  1. La devolución de llamada para el miembro sis es lo que invoca la llamada hgetall; por lo tanto, está impidiendo implícitamente que estos comandos se canalicen juntos para cualquier llamada del miembro sis. La devolución de llamada no se invoca hasta que Redis responde.
  2. Si base y client son clientes de Redis diferentes, NUNCA podrían compartir la misma canalización.

Los comandos deben ejecutarse desde el mismo contexto * para ver algún beneficio de la canalización. Por ejemplo, similar al ejemplo de PING en los documentos de canalización de 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()
})

* o desde contextos separados si se envía más rápido de lo que responde Redis, pero nunca responda contextos dependientes

Todos 9 comentarios

¿Se hace a través de los comandos client.multi y multi.exec?

Hola @saritasa , la canalización es automática. Siempre sucede dentro del cliente. No es necesario utilizar multi o exec para habilitarlo.

Hola Bryce,

  1. Estoy confundido, ¿cuál es el propósito de las funciones "múltiples" dentro de node_redis entonces?
  2. ¿Cuál es el algoritmo utilizado para canalizar automáticamente los comandos?

Gracias,
Dmitry

Las operaciones múltiples provienen de la especificación del protocolo Redis, tienen un propósito transaccional fuera de la canalización: http://redis.io/commands/multi

En términos de cómo funciona la canalización: http://redis.io/topics/pipelining, esto es solo una cuestión de que el cliente escriba comandos en Redis tan rápido como los envíe sin esperar la respuesta antes de escribir la siguiente. El cliente realiza un seguimiento de los comandos enviados y luego realinea las respuestas con los comandos enviados una vez que Redis responde.

Gracias Bryce, entiendo cómo funciona http://redis.io/topics/pipelining . en una aplicación node.js: ¿cómo se debe estructurar el código para que las solicitudes se canalicen?

así que en el siguiente ejemplo

hgetall & expire: ¿están canalizados o no? Una de las llamadas es la devolución de llamada interna.


function getByID (table, id, next) {
if (! Success) return setTimeout (function () {
getByID (tabla, id, siguiente);
}, 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 los comandos se envían "en canalización", pero estos nunca se enviarían en el mismo marco de escritura de canalización por una o dos razones:

  1. La devolución de llamada para el miembro sis es lo que invoca la llamada hgetall; por lo tanto, está impidiendo implícitamente que estos comandos se canalicen juntos para cualquier llamada del miembro sis. La devolución de llamada no se invoca hasta que Redis responde.
  2. Si base y client son clientes de Redis diferentes, NUNCA podrían compartir la misma canalización.

Los comandos deben ejecutarse desde el mismo contexto * para ver algún beneficio de la canalización. Por ejemplo, similar al ejemplo de PING en los documentos de canalización de 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()
})

* o desde contextos separados si se envía más rápido de lo que responde Redis, pero nunca responda contextos dependientes

lo tengo ahora - ¡gracias! ¡Este es un comentario muy valioso!

Creo que la "canalización automática" de node_redis no es la canalización a la que se refieren los redis oficiales.

Este tiempo se denomina RTT (tiempo de ida y vuelta). Es muy fácil ver cómo esto puede afectar el rendimiento cuando un cliente necesita realizar muchas solicitudes seguidas (por ejemplo, agregar muchos elementos a la misma lista o completar una base de datos con muchas claves). Por ejemplo, si el tiempo de RTT es de 250 milisegundos (en el caso de un enlace muy lento a través de Internet), incluso si el servidor puede procesar 100k solicitudes por segundo, podremos procesar a un máximo de cuatro solicitudes por segundo.
Si la interfaz utilizada es una interfaz de bucle invertido, el RTT es mucho más corto (por ejemplo, mi host informa 0,044 milisegundos haciendo ping 127.0.0.1), pero aún es mucho si necesita realizar muchas escrituras seguidas.

Lo que significa la canalización por redis oficial es combinar varios comandos y enviarlos una vez para contrarrestar la latencia debido a RTT, que no es abordado por node_redis. Y la "canalización automática" en node_redis en realidad está enviando tantos comandos como sea posible al mismo tiempo utilizando el modelo de programación asíncrona de Node.

Aquí hay un buen artículo sobre este tema. http://informatikr.com/2012/redis-pipelining.html

@Vizwind @saritasa tanto .multi como .batch usan la canalización como se pensó a partir de la versión 2.2.

¿Fue útil esta página
0 / 5 - 0 calificaciones