sql >> Base de Datos >  >> NoSQL >> Redis

Node redis Publisher consume demasiada memoria

Aquí hay dos preguntas.

¿Por qué el programa requiere tanta memoria?

Creo que se debe a la falta de contrapresión.

Su secuencia de comandos solo envía 1 millón de comandos de publicación a Redis, pero no procesa ninguna respuesta a estos comandos (que, por lo tanto, node_redis simplemente descarta). Debido a que nunca espera una respuesta, el script acumulará mucho contexto en la memoria para todos estos comandos. node_redis necesita mantener un contexto para realizar un seguimiento de los comandos y asociar comandos y respuestas de Redis. Node.js es más rápido para poner en cola los comandos que el sistema para transmitir esos comandos a Redis, procesarlos, generar respuestas y transmitir las respuestas a node.js. Por lo tanto, el contexto está creciendo y representa mucha memoria.

Si desea mantener el consumo de memoria en un nivel aceptable, debe reducir su código para darle la oportunidad a node.js de procesar las respuestas de Redis. Por ejemplo, el siguiente script también procesa 1 millón de elementos, pero los publica como lotes de 1000 elementos y espera las respuestas cada 1000 elementos. Por lo tanto, consume muy poca memoria (el contexto contiene como máximo 1000 comandos pendientes).

var redis = require("redis"),
    publisher = redis.createClient();

function loop( callback ) {
   var count = 0;
   for ( i=0 ; i < 1000; ++i ) {
        publisher.publish("rChat", i, function(err,rep) {
        if ( ++count == 1000 )
            callback();
        });
   }
}

function loop_rec( n, callback ) {
    if ( n == 0 ) {
        callback();
        return;
    }
    loop( function() {
        loop_rec( n-1, callback );
    });
}

function main() {
    console.log("Hello");
    loop_rec(1000, function() {
        console.log("stopped sending messages");
        setTimeout(function(){publisher.end();},1000);
        return;
    });
}

publisher.ping(main)

setTimeout(function() {
    console.log("Keeping console alive");
}, 1000000);

¿Se puede liberar la memoria?

Por lo general, no puede. Como todos los programas C/C++, node.js usa un asignador de memoria. Cuando se libera memoria, no se libera al sistema, sino al asignador de memoria. Generalmente, el asignador de memoria no puede devolver la memoria no utilizada al sistema. Tenga en cuenta que no se trata de una fuga, ya que si el programa realiza una nueva asignación, la memoria se reutilizará.

Escribir un programa C/C++ que realmente pueda liberar memoria al sistema generalmente implica diseñar un asignador de memoria personalizado. Pocos programas C/C++ lo hacen. Además de eso, node.js incluye un recolector de basura con v8, por lo que debería imponer restricciones adicionales en la política de liberación de memoria.