2016-08-09 426 views
1

Ich baue einen Server, der Dateien von Endpunkt A zu Endpunkt B überträgt.Ist NodeJs Stream symmetrisch?

Ich frage mich, ob die NodeJs Stream-Pipe symmetrisch ist? Wenn ich Folgendes tue: request.get(A).pipe(request.put(B));, lädt es so schnell wie es lädt?

Ich stelle diese Frage, weil mein Server eine asymmetrische Verbindung hat (es lädt schneller als Upload), und ich versuche Speicherverbrauch zu vermeiden.

Antwort

1

Gemäß Knoten documentation on stream#pipe wird Pipe den Lesestrom in den fließenden Modus wechseln - es wird nur lesen, wenn der Schreibstrom die Verwendung früherer Pakete beendet hat.

Die lesable.pipe() -Methode fügt dem lesbaren Stream einen Writeable-Stream hinzu, der automatisch in den fließenden Modus wechselt und alle Daten in das angehängte Writable verschiebt. Der Datenfluss wird automatisch verwaltet, sodass der beschreibbare Zielstream nicht von einem schnelleren lesbaren Stream überlastet wird.

So kann die Übertragung asymmetrisch sein, aufgrund der unterschiedlichen Sende-/Download-Geschwindigkeit - der Unterschied in dem Knoten Speicher gepuffert werden kann - Buffering of streams

Buffering #

Sowohl beschreibbaren und auslesbaren Ströme speichern Daten in einem internen Puffer, der mit writable._writableState.getBuffer() bzw. lesable._readableState.buffer abgerufen werden kann.

Die Menge der potenziell gepufferten Daten hängt von der Option highWaterMark ab, die an den Stream-Konstruktor übergeben wird. Bei normalen Streams gibt die Option highWaterMark die Gesamtzahl der Bytes an. Bei Streams , die im Objektmodus arbeiten, gibt der highWaterMark eine Gesamtanzahl von Objekten an.

Daten werden in lesbaren Streams gepuffert, wenn die Implementierung stream.push (Chunk) aufruft. Wenn der Consumer des Streams stream.read() nicht aufruft, werden die Daten in der internen Warteschlange gespeichert, bis sie verbraucht sind.

Sobald die Gesamtgröße des internen Lesepuffer die Schwelle spezifiziert durch high water erreicht, wird der Strom vorübergehend Daten von der darunter liegenden Ressource aufhören zu lesen, bis die Daten zur Zeit gepufferte verbraucht werden kann (das heißt, der Strom hört auf, die interne lesable._read() -Methode aufzurufen, die zum Füllen des Lesepuffers verwendet wird).

Daten werden in beschreibbaren Streams gepuffert, wenn die Methode writable.write (chunk) wiederholt aufgerufen wird. Während die Gesamtgröße des internen Schreibpuffers unter dem durch highWaterMark festgelegten Schwellenwert liegt, geben Aufrufe an writable.write() true zurück. Sobald die Größe des internen Puffers die highWaterMark erreicht oder überschreitet, wird false zurückgegeben.

Ein Hauptziel der Stream-API und insbesondere der Stream.pipe() Methode, ist die Pufferung von Daten auf akzeptable Ebenen wie zu begrenzen, dass Quellen und Ziele unterschiedlicher Geschwindigkeiten den verfügbaren Speicher nicht überwältigen.

Da Duplex und Transströme sowohl les- und beschreibbar sind, jeweils halten zwei separaten internen Puffer für das Lese und Schreiben verwendet , wobei jede Seite unabhängig von den anderen betrieben werden kann, während ein angemessenen und effizienten Datenfluss aufrechterhalten wird. Für Beispiel sind net.Socket-Instanzen Duplex-Streams, deren lesbare Seite den Verbrauch von Daten ermöglicht, die vom Socket empfangen werden und deren Schreibbare -Seite das Schreiben von Daten in den Socket ermöglicht. Da Daten in den Socket mit einer schnelleren oder langsameren Rate als Daten empfangen werden können, ist es wichtig, dass jede Seite unabhängig von der anderen arbeitet (und Puffer).

Ich empfehle Ihnen, schauen Sie sich this question hier wird das Thema weiter ausgearbeitet.

Wenn Sie das folgende Beispiel ausführen

const http = require('http'); 

http.request({method:'GET', host:'somehost.com', path: '/cat-picture.jpg'}, (response)=>{ 
    console.log(response); 
}).end() 

können Sie die zugrunde liegenden Steckdosen erkunden - auf meinem System alles, was sie haben die highWaterMark : 16384 Eigenschaft. Also, wenn ich die Dokumentation und die oben genannten Fragen verstehe, in Ihrem Fall über 16 KB kann in der schnelleren GET Socket auf Node.js Ebene gepuffert werden - was passiert, ist wahrscheinlich stark abhängig von Ihrem System/Netzwerk-Konfiguration.

+0

Ok. Vielen Dank. Wenn Sie wirklich verstehen, wird die Download-Anfrage während des Uploads (für den laufenden Chunk) pausiert? – user3100287

+0

@ user3100287 Ich habe meine Antwort ein wenig verbessert, aber ich fühle, dass sie noch unvollständig ist. Ich habe einige gute Stackoverflow-Fragen angesprochen, die Ihnen helfen könnten, das Problem zu verstehen. –

+0

danke für diese Erklärung :) – user3100287