sql >> Database >  >> NoSQL >> Redis

Node redis uitgever verbruikt te veel geheugen

Er zijn hier twee vragen.

Waarom vereist het programma zoveel geheugen?

Ik denk dat het komt door het gebrek aan tegendruk.

Uw script stuurt slechts 1 miljoen publicatieopdrachten naar Redis, maar het verwerkt geen enkele reactie op deze opdrachten (die daarom gewoon worden weggegooid door node_redis). Omdat het nooit op een antwoord wacht, verzamelt het script veel context in het geheugen voor al deze opdrachten. node_redis moet een context behouden om de commando's bij te houden en Redis-commando's en antwoorden te koppelen. Node.js is sneller om commando's in de wachtrij te plaatsen dan het systeem om die commando's naar Redis te sturen, ze te verwerken, antwoorden op te bouwen en antwoorden terug te sturen naar node.js. De context groeit daarom en het vertegenwoordigt veel geheugen.

Als u het geheugenverbruik op een acceptabel niveau wilt houden, moet u uw code verlagen om node.js de kans te geven Redis-antwoorden te verwerken. Het volgende script verwerkt bijvoorbeeld ook 1 miljoen items, maar publiceert ze als batches van 1000 items en wacht op de antwoorden om de 1000 items. Het verbruikt daarom heel weinig geheugen (de context bevat maximaal 1000 wachtende opdrachten).

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);

Kan het geheugen worden vrijgegeven?

Meestal kan dat niet. Zoals alle C/C++-programma's gebruikt node.js een geheugentoewijzer. Wanneer geheugen wordt vrijgemaakt, wordt het niet vrijgegeven aan het systeem, maar aan de geheugentoewijzer. Over het algemeen is de geheugentoewijzer niet in staat om het ongebruikte geheugen terug te geven aan het systeem. Let op:het is geen lek, want als het programma een nieuwe toewijzing uitvoert, wordt het geheugen hergebruikt.

Het schrijven van een C/C++-programma dat daadwerkelijk geheugen aan het systeem kan vrijgeven, omvat over het algemeen het ontwerpen van een aangepaste geheugenallocator. Er zijn maar weinig C/C++ programma's die het doen. Bovendien bevat node.js een garbage collector met v8, dus het zou extra beperkingen moeten stellen aan het beleid voor het vrijgeven van geheugen.




  1. Mongoose - RangeError:maximale call-stackgrootte overschreden

  2. MongoDB:Hoe meerdere documenten bijwerken met één enkele opdracht?

  3. Update toepassen met gefilterde positionele operator met arrayFilters

  4. Percona Live 2017 - Samenvatting van Meerderen