Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Wydawca Node redis zużywa zbyt dużo pamięci

Tutaj są dwa pytania.

Dlaczego program wymaga tyle pamięci?

Myślę, że wynika to z braku przeciwciśnienia.

Twój skrypt po prostu wysyła 1M poleceń publikowania do Redis, ale nie przetwarza żadnych odpowiedzi na te polecenia (które są zatem po prostu odrzucane przez node_redis). Ponieważ nigdy nie czeka na żadną odpowiedź, skrypt zgromadzi w pamięci dużo kontekstu dla wszystkich tych poleceń. node_redis musi zachować kontekst, aby śledzić polecenia i kojarzyć polecenia i odpowiedzi Redis. Node.js jest szybszy do kolejkowania poleceń, niż system ma przekazywać te polecenia do Redis, przetwarzać je, budować odpowiedzi i przekazywać odpowiedzi z powrotem do node.js. Kontekst zatem rośnie i reprezentuje dużo pamięci.

Jeśli chcesz utrzymać zużycie pamięci na akceptowalnym poziomie, musisz ograniczyć kod, aby umożliwić node.js przetworzenie odpowiedzi Redis. Na przykład poniższy skrypt przetwarza również 1 mln elementów, ale publikuje je jako partie po 1000 elementów i czeka na odpowiedzi co 1000 elementów. W związku z tym zużywa bardzo mało pamięci (kontekst zawiera maksymalnie 1000 oczekujących poleceń).

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

Czy pamięć można zwolnić?

Zwykle nie. Jak wszystkie programy C/C++, node.js używa alokatora pamięci. Zwolniona pamięć nie jest zwalniana do systemu, ale do alokatora pamięci. Generalnie alokator pamięci nie jest w stanie zwrócić nieużywanej pamięci do systemu. Pamiętaj, że nie jest to wyciek, ponieważ jeśli program wykona nową alokację, pamięć zostanie ponownie wykorzystana.

Napisanie programu w języku C/C++, który faktycznie może zwolnić pamięć do systemu, zazwyczaj wiąże się z zaprojektowaniem niestandardowego alokatora pamięci. Niewiele programów C/C++ to robi. Co więcej, node.js zawiera garbage collector z v8, więc powinien nakładać dodatkowe ograniczenia na politykę zwalniania pamięci.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Komunikacja między dwoma kontenerami Docker w systemie macOS 10.12

  2. Błąd Redis Cross Slot

  3. Jak utrzymać serwer redis działający?

  4. Wydanie z wieloma wkładkami Redis

  5. Jak sprawdzić, czy sidekiq jest podłączony do serwera redis?