Heim  >  Artikel  >  Web-Frontend  >  Eine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js

Eine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js

不言
不言Original
2018-08-01 15:54:462880Durchsuche

Dieser Artikel stellt Ihnen eine kurze Diskussion über hohe Parallelität und verteilte Cluster in node.js vor. Ich hoffe, dass er für Sie hilfreich ist.

Knotenfunktionen: hohe Parallelität

Bevor Sie erklären, warum Knoten eine hohe Parallelität erreichen können, können Sie sich auch einige andere Funktionen von Knoten ansehen:

Single-Threaded

Lassen Sie uns zunächst ein Konzept klären, das heißt: Knoten ist 单线程, was den Eigenschaften von JavaScript im Browser entspricht, und im Knoten unterscheidet sich der JavaScript-Hauptthread von anderen Threads (z. B. E/A-Threads) können den Status nicht teilen.

Der Vorteil eines einzelnen Threads ist:

  • Es besteht keine Notwendigkeit, auf das Statussynchronisationsproblem zwischen Threads wie Multithreading zu achten

  • Es entsteht kein Overhead durch Threadwechsel

  • Kein Deadlock existiert

Natürlich hat Single Threading auch viele Nachteile:

  • Multi-Core-CPU kann nicht vollständig ausgenutzt werden

  • Eine große Anzahl von Berechnungen, die die CPU belegen, führt zu Anwendungsblockaden (d. h. nicht geeignet für CPU- intensiv)

  • Fehler führen zum Beenden der gesamten Anwendung

Heute scheint es jedoch, dass diese Nachteile kein Problem mehr darstellen oder waren entsprechend gelöst:

(1) Prozess- oder Unterteilungsinstanz erstellen

Was das erste Problem betrifft, ist die einfachste Lösung die Verwendung des child_process-Kernmoduls oder -Clusters: child_process und net kombinierte Anwendung. Wir können jeden Kern voll ausnutzen, indem wir mehrere Prozesse auf einem Multi-Core-Server erstellen (normalerweise mithilfe einer Fork-Operation), müssen uns jedoch mit Kommunikationsproblemen zwischen Prozessen befassen.

Eine andere Lösung besteht darin, dass wir die physische Maschine in mehrere virtuelle Maschinen mit einem Kern aufteilen und Tools wie pm2 verwenden können, um mehrere virtuelle Maschinen zu verwalten, um eine Cluster-Architektur zu bilden, um die erforderlichen Dienste effizient auszuführen Ich werde hier nicht auf die Kommunikation (Statussynchronisierung) zwischen Maschinen eingehen, sondern sie im Folgenden in der verteilten Knotenarchitektur ausführlich erläutern.

(2) Zeitscheibenrotation

Was den zweiten Punkt betrifft, glaube ich nach Diskussion mit meinen Freunden, dass wir die Zeitscheibenrotation verwenden können, um Multithreading in einem einzelnen Thread zu simulieren und entsprechend zu reduzieren Anwendungsblockierung. Gefühl (obwohl diese Methode nicht wirklich Zeit spart wie Multithreading)

(3) Lastausgleich, Überwachung/Isolierung toter Pixel

Was den dritten Punkt betrifft, meine Freunde und I Wir haben auch besprochen, dass der Hauptproblempunkt darin besteht, dass sich der Knoten von JAVA unterscheidet und die von ihm implementierte Logik hauptsächlich asynchron ist.

Dies führt dazu, dass der Knoten Try/Catch nicht so bequem wie JAVA zum Abfangen und Umgehen von Fehlern verwenden kann, da nicht bestimmt werden kann, wann die asynchrone Aufgabe die Ausnahme zurückgibt. In einer Single-Thread-Umgebung bedeutet das Versäumnis, Fehler zu umgehen, dass die Anwendung beendet wird und die Lücke zwischen Neustart und Wiederherstellung zu Dienstunterbrechungen führt, die wir nicht sehen möchten.

Da die Serverressourcen jetzt reichlich vorhanden sind, können wir natürlich Tools wie pm2 oder nginx verwenden, um den Dienststatus dynamisch zu bestimmen. Isolieren Sie den fehlerhaften Pixelserver, wenn ein Dienstfehler auftritt, leiten Sie die Anforderung an den normalen Server weiter und starten Sie den fehlerhaften Pixelserver neu, um weiterhin Dienste bereitzustellen. Dies ist auch Teil der verteilten Architektur von Node.

Asynchrone E/A

Da es sich bei dem Knoten um einen Single-Thread handelt und alle Ereignisse in einem Thread verarbeitet werden, fragen Sie sich vielleicht, ob das nicht sehr ineffizient sein und einer hohen Parallelität widersprechen sollte?

Im Gegenteil, die Leistung des Knotens ist sehr hoch. Einer der Gründe dafür ist, dass der Knoten über die Funktion 异步I/O verfügt. Immer wenn eine E/A-Anfrage auftritt, stellt der Knoten einen E/A-Thread für die Anfrage bereit. Dann kümmert sich der Knoten nicht um den E/A-Vorgangsprozess, sondern führt das Ereignis weiterhin im Hauptthread aus. Es muss nur verarbeitet werden, wenn die Anforderung den Rückruf zurückgibt. Das heißt, Node spart viel Zeit beim Warten auf Anfragen.

Dies ist auch einer der wichtigen Gründe, warum der Knoten eine hohe Parallelität unterstützt.

Tatsächlich sind nicht nur E/A-Vorgänge, sondern auch die meisten Vorgänge des Knotens asynchron. in einer Art und Weise durchgeführt. Es ist wie ein Organisator, der nicht alles persönlich erledigen muss. Er muss den Mitgliedern nur sagen, wie sie richtig vorgehen, Feedback annehmen und wichtige Schritte durchführen, damit das gesamte Team effizient arbeiten kann.

Transaktionsgesteuert

Vielleicht möchten Sie noch einmal fragen: Woher weiß der Knoten, dass die Anfrage einen Rückruf zurückgegeben hat, und wann sollte er diese Rückrufe verarbeiten?

Die Antwort ist eine weitere Funktion des Knotens: 事务驱动, das heißt, der Hauptthread führt das Programm aus, indem er die Ereignisschleife auslöst

Dies ist eine weitere Möglichkeit, wie der Knoten eine hohe Parallelität unterstützt . Wichtige Gründe

Diagramm der Ereignisschleife in der Knotenumgebung:

   ┌───────────────────────┐
┌─>│        timers         │<p><strong>Umfragephase: </strong></p><p>Beim Eintritt in die Umfragephase und dort Es gibt keine Timer. Beim Aufruf geschieht Folgendes: </p><p> (1) Wenn die Umfragewarteschlange nicht leer ist: </p>
  • Ereignisschleife führt den Rückruf in der Umfragewarteschlange aus synchron (neues I/O-Ereignis), bis die Warteschlange leer ist oder der ausgeführte Callback online geht.

(2) Wenn die Umfragewarteschlange leer ist:

  • Wenn das Skript setImmediate() aufruft, beendet die Ereignisschleife die Umfragephase und geben Sie ein: Führen Sie den Rückruf von setImmediate() in der Prüfphase aus.

  • Wenn das Skript nicht von setImmediate() aufgerufen wird, wartet die Ereignisschleife darauf, dass Rückrufe (neue E/A-Ereignisse) zur Warteschlange hinzugefügt werden, und führt sie dann sofort aus.

Beim Eintritt in die Umfragephase und beim Aufrufen von Timern geschieht Folgendes:

  • Sobald die Umfragewarteschlange leer ist, prüft die Ereignisschleife, ob Timer, Wenn ein oder mehrere Timer angekommen sind, kehrt die Ereignisschleife zur Timer-Phase zurück und führt die Rückrufe dieser Timer aus (dh gibt den nächsten Tick ein).

Priorität:

Nächste Tick-Warteschlange > MicroTask-Warteschlange

setTimeout, setInterval > setImmediate

Da der Timer den Timer aus dem Rot-Schwarz-Baum herausnehmen muss, um zu bestimmen, ob die Zeit angekommen ist, beträgt die Zeitkomplexität O(lg(n)). Wenn Sie also ein Ereignis sofort asynchron ausführen möchten, ist es am besten, dies nicht zu tun setTimeout(func, 0) zu verwenden. Verwenden Sie stattdessen „process.nextTick()“, um dies zu tun.

Verteilte Knotenarchitektur

Die Knotenclusterarchitektur, die ich gelernt habe, ist hauptsächlich in die folgenden Module unterteilt:

Nginx (Lastausgleich, Planung) -> ;Knotencluster-> Redis (Synchronisationsstatus)

Ich habe ein Bild nach meinem Verständnis organisiert:

Eine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js

Dies sollte eine ideale Architektur sein. Denn obwohl das Lesen/Schreiben von Redis recht schnell ist, liegt dies daran, dass es Daten im Speicherpool speichert und entsprechende Vorgänge im Speicher ausführt.

Das ist ziemlich hoch für die Speicherauslastung des Servers, daher fügen wir normalerweise immer noch MySQL zur Architektur hinzu, wie unten gezeigt:

Eine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js

Erklären Sie zuerst dieses Bild:
Wenn Benutzerdaten eintreffen, werden die Daten zuerst in MySQL geschrieben. Wenn der Knoten die Daten benötigt, wird er an Redis gesendet, um sie zu lesen. Wenn sie nicht gefunden werden, werden sie an MySQL gesendet Um die gewünschten Daten abzufragen und zu schreiben, geben Sie Redis ein, und Sie können bei der nächsten Verwendung direkt in Redis abfragen.

Die Vorteile des Hinzufügens von MySQL im Vergleich zum reinen Lesen/Schreiben in Redis sind:

(1) Vermeiden Sie, kurzfristig nutzlose Daten in Redis zu schreiben, Speicher zu belegen und die Belastung von Redis zu verringern

(2) Wenn in der späteren Phase spezifische Abfragen und Datenanalysen erforderlich sind (z. B. die Analyse der Zunahme der Benutzer bei betrieblichen Aktivitäten), können relationale SQL-Abfragen eine große Hilfe sein

Natürlich Wenn der Datenverkehr in kurzer Zeit verarbeitet wird, können wir Daten auch direkt in Redis schreiben, um den Zweck zu erreichen, Daten schnell zu speichern und die Fähigkeit des Servers zu erhöhen, den Datenverkehr zu bewältigen Daten separat an MySQL übertragen.

Nachdem wir kurz die allgemeine Architekturzusammensetzung vorgestellt haben, werfen wir einen genaueren Blick auf die Details jedes Teils:

Verkehrszugriffsschicht

Was die Verkehrszugriffsschicht tut, ist Alles akzeptiert Der Verkehr wird verarbeitet und die folgenden Dienste werden bereitgestellt:

  • Verkehrspufferung

  • Umleitung und Weiterleitung

Eine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js

  • Timeout-Erkennung

    • Timeout beim Herstellen einer Verbindung mit dem Benutzer

    • Zeitüberschreitung beim Lesen des Benutzertexts

    • Zeitüberschreitung beim Herstellen einer Verbindung zum Backend

    • Zeitüberschreitung beim Lesen des Backend-Antwortheaders

    • Zeitüberschreitung beim Schreiben der Antwort

    • Lange Zeitüberschreitung bei der Verbindung mit dem Benutzer

  • Cluster-Zustandsprüfung/-Isolation Schlecht Pixelserver

    • Isolieren Sie den fehlerhaften Pixelserver und versuchen Sie, ihn zu reparieren/neu zu starten, bis der Server wieder normal ist

  • Fehler erneut Testmechanismus

    • Nachdem die Anfrage an eine bestimmte Maschine in einem bestimmten Cluster weitergeleitet wurde und ein Fehler zurückgegeben wurde, wird die Anfrage an andere Maschinen im Cluster weitergeleitet, oder an Maschinen über Cluster hinweg erneut versuchen

  • Verbindungspooling/Sitzungspersistenzmechanismus

    • Verwenden Sie den Verbindungspoolingmechanismus für verzögerungsempfindliche Benutzer um die Verbindungsaufbauzeit zu verkürzen

  • Sicherheitsschutz

  • Datenanalyse

Bei Weiterleitung zu jedem Produkt Nachdem Sie online gegangen sind, ist es Zeit, an der Lastschicht zu arbeiten: Leiten Sie die Anfrage je nach Situation an verschiedene Computerräume weiter

Eine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js

Natürlich , diese Plattform ist nicht auf die Weiterleitung beschränkt, Sie können sie als großes privates Cloud-System verstehen, das die folgenden Dienste bereitstellt:

  • Datei-Upload/Online-Bereitstellung von Diensten

  • Zeile Ändern Sie die Konfiguration

  • Geplante Aufgaben festlegen

  • Online-Systemüberwachung/Protokolldruckdienst

  • Online-Instanzverwaltung

  • Spiegelcenter

  • usw....

Knotenclusterschicht

Die Hauptaufgabe dieser Schicht ist:

(1) Schreiben Sie zuverlässigen Knotencode und stellen Sie Back-End-Dienste für den Bedarf bereit

(2) Schreiben Sie leistungsstarke Abfrageanweisungen, interagieren Sie mit Redis und MySQL und verbessern Sie die Abfrageeffizienz

(3) Synchronisieren Sie den Status jedes Knotendienstes im Cluster über Redis

(4) Übergeben Sie die Hardware-Verwaltungsplattform, verwalten/überwachen Sie den Status physischer Maschinen, verwalten Sie IP-Adressen usw. (Tatsächlich scheint es unangemessen, diesen Teil der Arbeit auf diese Ebene zu legen, aber ich weiß nicht, um welche Ebene es sich handelt sollte platziert werden auf...)

(Natürlich liste ich die Einträge in diesem Teil nur kurz auf, es braucht immer noch Zeit, sie zu sammeln und gründlich zu verstehen)

Datenbankschicht

Die Hauptarbeit dieser Ebene ist:

(1) MySQL erstellen und verwandte Seiten und Tabellen entwerfen; erforderliche Indizes und Fremdschlüssel einrichten, um den Abfragekomfort zu verbessern

(2) Redis bereitstellen und Bereitstellung entsprechender Schnittstellen zur Knotenschicht

Verwandte Empfehlungen:

Wie Vue Axios verwendet, um Backend-Daten anzufordern

Analyse der Formulareingabebindung und Komponentengrundlagen in Vue

Das obige ist der detaillierte Inhalt vonEine kurze Diskussion über hohe Parallelität und verteiltes Clustering in node.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn