Was macht Node.js speziell skalierbarer als Apache?

73

Um ehrlich zu sein, habe ich es noch nicht vollständig verstanden - und ich verstehe sogar, wie Node.js als einzelner Thread mit dem Ereignismodell funktioniert. Ich verstehe nur nicht, wie das besser ist als Apache und wie es horizontal skaliert, wenn es Single-Threaded ist.

MaiaVictor
quelle

Antworten:

92

Ich habe festgestellt, dass dieser Blog-Beitrag von Tomislav Capan es sehr gut erklärt:
Warum zum Teufel sollte ich Node.js verwenden? Eine Einführung von Fall zu Fall

Meine Interpretation des Kerns für Node 0.10 im Vergleich zu Apache:

Die guten Teile

  • Node.js vermeidet das Hochfahren von Threads für jede Anforderung oder muss das Zusammenführen von Anforderungen zu einer Reihe von Threads nicht wie Apache behandeln. Daher ist der Aufwand für die Bearbeitung von Anfragen geringer und die schnelle Reaktion hervorragend.
  • Node.js kann die Ausführung der Anforderung an eine separate Komponente delegieren und sich auf neue Anforderungen konzentrieren, bis die delegierte Komponente mit dem verarbeiteten Ergebnis zurückkehrt. Dies ist asynchroner Code und wird durch das Ereignismodell ermöglicht. Apache führt Anforderungen seriell innerhalb eines Pools aus und kann den Thread nicht wiederverwenden, wenn eines seiner Module lediglich auf den Abschluss einer Aufgabe wartet. Apache stellt dann Anforderungen in die Warteschlange, bis ein Thread im Pool wieder verfügbar ist.
  • Node.js spricht mit JavaScript und ist daher sehr schnell beim Durchlaufen und Bearbeiten von JSON, das von externen Web-API-Quellen wie MongoDB abgerufen wurde, wodurch der Zeitaufwand pro Anforderung reduziert wird. Apache-Module wie PHP benötigen möglicherweise mehr Zeit, da sie JSON nicht effizient analysieren und bearbeiten können, da sie Marshalling benötigen , um die Daten zu verarbeiten.

Die schlechten Teile

Hinweis: Die meisten der unten aufgeführten fehlerhaften Teile werden mit der kommenden Version 0.12 verbessert.

  • Node.js nervt mit rechenintensiven Aufgaben , da es aufgrund seines einzelnen Threads alle anderen eingehenden Anforderungen in die Warteschlange stellt, wenn etwas lange ausgeführt wird. In Apache stehen im Allgemeinen mehr Threads zur Verfügung, und das Betriebssystem plant die CPU-Zeit zwischen diesen Threads genau und fair, sodass neue Threads weiterhin verarbeitet werden können, wenn auch etwas langsamer. Außer wenn alle verfügbaren Threads in Apache Anforderungen verarbeiten, beginnt Apache auch, Anforderungen in die Warteschlange zu stellen.
  • Node.js nutzt Multi-Core-CPUs nicht vollständig aus , es sei denn, Sie erstellen einen Node.js-Cluster oder starten untergeordnete Prozesse. Wenn Sie die beiden letzteren ausführen, können Sie ironischerweise mehr Orchestrierungsaufwand hinzufügen, das gleiche Problem wie bei Apache. Logischerweise könnten Sie auch mehr Node.js-Prozesse starten, dies wird jedoch nicht von Node.js verwaltet. Sie müssten Ihren Code testen, um zu sehen, was besser funktioniert. 1) Multithreading aus Node.js mit Clustern und untergeordneten Prozessen oder 2) mehrere Node.js-Prozesse.

Milderungen

Alle Serverplattformen haben eine Obergrenze. Node.js und Apache werden es irgendwann erreichen.

  • Node.js erreicht es am schnellsten, wenn Sie schwere Rechenaufgaben haben.
  • Apache erreicht es am schnellsten, wenn Sie Tonnen kleiner Anfragen darauf werfen, die eine lange serielle Ausführung erfordern.

Drei Dinge, die Sie tun können, um den Durchsatz von Node.js zu skalieren

  1. Nutzen Mehradercpus , entweder durch Einrichten eines Clusters , die Verwendung untergeordneten Prozessen , oder verwenden ein Multi-Prozess - orchestrator wie Phusion Passagier .
  2. Richten Sie Worker-Rollen ein, die mit einer Nachrichtenwarteschlange verbunden sind . Dies ist die effektivste Lösung für rechenintensive, lang laufende Anforderungen. Entladen Sie sie auf eine Arbeiterfarm. Dadurch werden Ihre Server in zwei Teile aufgeteilt. 1) öffentlich zugängliche Büro-Server, die Anforderungen von Benutzern annehmen, und 2) private Worker-Server, die lang laufende Aufgaben erledigen. Beide sind mit einer Nachrichtenwarteschlange verbunden. Die Büro-Server fügen der Warteschlange Nachrichten (eingehende Anfragen mit langer Laufzeit) hinzu. Die Worker-Rollen warten auf eingehende Nachrichten, verarbeiten diese und geben das Ergebnis möglicherweise in die Nachrichtenwarteschlange zurück. Wenn eine Anforderung / Antwort erforderlich ist, kann der Verwaltungsserver asynchron warten, bis die Antwortnachricht in der Nachrichtenwarteschlange eintrifft. Beispiele für Nachrichtenwarteschlangen sind RabbitMQ und ZeroMQ .
  3. Richten Sie einen Load Balancer ein und starten Sie weitere Server. Jetzt, da Sie Hardware effizient nutzen und lang laufende Aufgaben delegieren, können Sie horizontal skalieren. Wenn Sie einen Load Balancer haben, können Sie weitere Büroserver hinzufügen. Mithilfe einer Nachrichtenwarteschlange können Sie weitere Arbeitsserver hinzufügen. Sie können dies sogar in der Cloud einrichten, um es bei Bedarf zu skalieren.
Bart Verkoeijen
quelle
Dies ist eine großartige Antwort. Besonders der Tipp zu MQ. Ich habe mich gefragt, welchen Nutzen sie haben. Vielen Dank!
Oligofren
4
Jede rechenintensive Aufgabe sollte asynchron ausgeführt werden. Der Knoten wäre praktisch unbrauchbar, ohne sich stark auf die asynchrone Ausführung von Aufgaben mit langer Laufzeit zu verlassen. Dies ist das Hauptmerkmal der Skalierbarkeit des Knotens (in Bezug auf einzelne Instanzen) und ist hier äußerst wichtig.
Adam Tolley
Toller Punkt @AdamTolley. Um das zu erweitern, meinte ich mit einer rechenintensiven Aufgabe eine, die nicht einfach in mehrere asynchrone Teile zerlegt werden kann. Etwas, das nur synchron auf der CPU gemacht werden muss. Zum Beispiel ein Bild rendern. Asynchroner Code hilft Ihnen dort nicht, wenn Sie ihn nicht an eine andere CPU oder einen anderen Prozess delegieren oder auslagern können. Wenn Sie eine Aufgabe jedoch aufteilen können, können andere asynchrone Aufgaben wie ein Betriebssystem zeitlich auf Ihren Punkt verteilt werden.
Bart Verkoeijen
Das reine TCP-Protokoll ist am besten als alle anderen, funktioniert jedoch nicht auf Commons-Site-Hosts. Einige Geschäftsleute zahlen 3.000 US-Dollar pro Monat für Cloud-Server, anstatt ein gemeinsames Hosting zu verwenden, das zufriedenstellend wäre.
Padronização SA
38

Es hängt davon ab, wie Sie es verwenden. Node.js ist standardmäßig ein Single-Thread, aber mit dem (relativ) neuen Cluster-Modul können Sie horizontal über mehrere Threads skalieren.

Darüber hinaus bestimmen Ihre Datenbankanforderungen auch, wie effektiv die Skalierung mit dem Knoten ist. Wenn Sie beispielsweise MySQL mit node.js verwenden, profitieren Sie nicht annähernd so viel wie mit MongoDB, da sowohl MongoDB als auch node.js ereignisgesteuert sind.

Der folgende Link enthält viele nützliche Benchmarks für Systeme mit unterschiedlichen Einstellungen: http://www.techempower.com/benchmarks/

Node.js hat nicht den höchsten Rang, aber im Vergleich zu anderen Setups mit Nginx (kein Apache auf ihren Tabellen, aber nah genug) funktioniert es ziemlich gut.

Auch hier hängt es stark von Ihren Bedürfnissen ab. Ich glaube, wenn Sie nur statische Websites bedienen, wird empfohlen, sich an einen traditionelleren Stack zu halten. Allerdings haben die Leute mit node.js einige erstaunliche Dinge für andere Bedürfnisse getan: http://blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/ (c10k? Ha!)

Bearbeiten: Es ist erwähnenswert, dass Sie wirklich nicht nur Apache durch node.js "ersetzen". Sie würden Apache UND PHP ersetzen (in einem typischen Lampenstapel).

Kevin Lee
quelle
1
Tolle Antwort und das erhöht tatsächlich meine Fragen. Erstens verstehe ich nicht ganz, was dieser Typ speziell gemacht hat - er hat 1 Arbeiter für jeden verfügbaren Kern hervorgebracht, oder? Was ist das Grid Voodoo, das er dort macht? Warum braucht er Nachrichten über Knoten, wenn er nur eine Hallo-Welt bedient? Außerdem kenne ich dort fast keine dieser Frameworks. Zum Beispiel dachte ich, es sei nur eine Programmiersprache. Gibt es einen Ort, an dem ich einen Überblick darüber bekommen kann, was los ist, was von denen tatsächlich ist und was sie tun? Das wäre wirklich toll. Vielen Dank!
MaiaVictor
2
Er verwendet tatsächlich nur einen Worker-Prozess für seinen Server. Er generiert dynamisch 500 Client-Instanzen mit Amazon EC2, um Verbindungen herzustellen (jeweils 2000 für insgesamt 1 Million) und diese Verbindungen mit dem einzelnen Prozess-Webserver aufrechtzuerhalten, während Nachrichten zwischen all diesen Clients hin und her gesendet werden. Ich hätte von seinem ersten Beitrag aus verlinken sollen, wo er bei 100.000 Verbindungen beginnt und sich hocharbeitet ( blog.caustik.com/2012/04/08/… ). Was Go und etc. betrifft, würde ich vorschlagen, nur darüber zu googeln.
Kevin Lee
Apache ist so gut, dass es internationale HTTP-Umfragen unterstützt, haha
Padronização SA