Ich erstelle ein Analysepaket und laut Projektanforderungen muss ich 1 Milliarde Zugriffe pro Tag unterstützen. Ja, "Milliarden". Mit anderen Worten, nicht weniger als 12.000 Treffer pro Sekunde und vorzugsweise etwas Platz zum Platzen. Ich weiß, dass ich dafür mehrere Server benötige, aber ich versuche, die maximale Leistung jedes Knotens herauszuholen, bevor ich "mehr Hardware draufbringe".
Im Moment habe ich den Teil zur Verfolgung von Treffern fertiggestellt und gut optimiert. Ich speichere die Anfragen so ziemlich nur direkt in Redis (für die spätere Verarbeitung mit Hadoop). Die Anwendung ist Python / Django mit einem Gunicorn für das Gateway.
Mein Ubuntu 10.04-Rackspace-Server mit 2 GB (keine Produktionsmaschine) kann ungefähr 1200 statische Dateien pro Sekunde verarbeiten (mit Apache AB als Benchmark für ein einzelnes statisches Asset). Zum Vergleich: Wenn ich den statischen Dateilink gegen meinen Tracking-Link austausche, erhalte ich immer noch ungefähr 600 Anfragen pro Sekunde. Ich denke, dies bedeutet, dass mein Tracker gut optimiert ist, da er nur um den Faktor 2 langsamer ist, als dasselbe statische Asset zu liefern wiederholt.
Wenn ich jedoch mit Millionen von Treffern vergleiche, bemerke ich ein paar Dinge -
- Keine Datenträgerverwendung - dies wird erwartet, da ich alle Nginx-Protokolle deaktiviert habe und mein benutzerdefinierter Code nichts anderes tut, als die Anforderungsdetails in Redis zu speichern.
- Nicht konstante Speichernutzung - Vermutlich aufgrund der Speicherverwaltung von Redis steigt meine Speichernutzung allmählich an und fällt dann wieder ab, aber das war noch nie mein Engpass.
- Die Systemlast schwankt zwischen 2 und 4, das System reagiert auch bei meinen schwersten Benchmarks noch und ich kann http://mysite.com/tracking/pixel mit geringer sichtbarer Verzögerung manuell anzeigen, während mein (anderer) Server 600 Anforderungen pro ausführt zweite.
- Wenn ich einen kurzen Test durchführe, sagen wir 50.000 Treffer (dauert etwa 2 m), erhalte ich stabile und zuverlässige 600 Anfragen pro Sekunde. Wenn ich einen längeren Test durchführe (bis jetzt bis zu 3,5 m ausprobiert), verringert sich mein R / S auf etwa 250.
Meine Fragen --
ein. Schaut es so aus, als würde ich diesen Server schon ausreizen? Ist die Nginx-Leistung von statischen Dateien mit 1.200 / s mit der Leistung anderer vergleichbar?
b. Gibt es gängige Nginx-Tunings für solche Großserienanwendungen? Ich habe Worker-Threads auf 64 und Gunicorn-Worker-Threads auf 8 gesetzt, aber das Optimieren dieser Werte scheint mir nicht viel zu helfen oder zu schaden.
c. Gibt es irgendwelche Linux-Level-Einstellungen, die meine eingehenden Verbindungen einschränken könnten?
d. Was kann dazu führen, dass sich meine Leistung bei Langzeittests auf 250 U / s verschlechtert? Auch hier ist der Speicher während dieser Tests nicht voll, und die Festplattennutzung ist gleich Null.
Danke im Voraus an alle :)
BEARBEITEN Hier ist meine Nginx-Konfiguration - http://pastie.org/1450749 - es handelt sich hauptsächlich um Vanille mit offensichtlich abgeschnittenem Fett.
quelle
Antworten:
Sie missbrauchen die worker_threads von Nginx. Es gibt absolut keine Notwendigkeit, so viele Arbeiter zu führen. Sie sollten so viele Worker ausführen, wie Sie über CPUs verfügen, und dies als "täglich" bezeichnen. Wenn Sie Gunicorn auf demselben Server ausführen, sollten Sie Nginx-Worker wahrscheinlich auf zwei beschränken. Andernfalls werden Sie die CPUs nur mit der gesamten Kontextumschaltung auslasten, die zum Verwalten all dieser Prozesse erforderlich ist.
quelle
Ich habe Nginx verwendet, um 5K-Anfragen pro Sekunde für statische Inhalte zu liefern. Sie können die Anzahl der worker_connections erhöhen, die derzeit auf 1024 festgelegt sind.
Die max_client-Berechnung wäre wie folgt.
Mit den Anweisungen worker_connections und worker_proces aus dem Hauptabschnitt können Sie den Wert maxclients berechnen:
max_clients = worker_processes * worker_connections
In einer Reverse-Proxy-Situation wird max_clients
max_clients = worker_processes * worker_connections / 4
http://wiki.nginx.org/EventsModule#worker_connections
Die Berechnung der maximalen Worker-Verbindungen ist einfach, sobald Sie die Kapazität Ihres Setups kennen. Die Gesamtkapazität / Anzahl der Kerne beträgt max. Worker-Verbindungen. Zur Berechnung der Gesamtkapazität gibt es mehrere Möglichkeiten.
Wenn die oben beschriebene Methode bei Ihnen nicht funktioniert, versuchen Sie es mit den folgenden Methoden. Ich gehe allgemein davon aus, dass RAM und IO ignoriert werden. Sie werden ebenfalls berücksichtigt, aber diese geben Ihnen Ausgangspunkte und Sie können von da an Anpassungen vornehmen.
Angenommen, die Bandbreite ist der Engpass, nehmen Sie die durchschnittliche Objektgröße, die nginx bereitstellt, und teilen Sie Ihre Bandbreite damit auf, und Sie erhalten die maximal unterstützten qps.
In der zweiten Annahme ist die CPU der Engpass. Messen Sie in diesem Fall die Anforderungszeit und dividieren Sie 1 durch diese und multiplizieren Sie sie mit der Anzahl der Kerne in Ihrem System. Dies gibt die Anzahl der Anfragen pro Sekunde an, die Nginx verarbeiten kann.
quelle