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
¿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,
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:
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.
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:
base
yclient
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:
* o desde contextos separados si se envía más rápido de lo que responde Redis, pero nunca responda contextos dependientes