Frage Wie viele Prozesse sollte ich in einem WSGIDaemonProcess angeben, während Django über mod_wsgi ausgeführt wird?


Angenommen, ich habe zwei Sites (Superuser und Serverfault), die von ihrem eigenen virtuellen Apache-Host auf einer Box ausgeführt werden. Die 2 Seiten werden von Django betrieben und laufen auf Apache mit mod-wsgi. Eine typische Konfigurationsdatei für eine der Seiten sieht wie folgt aus:

WSGIDaemonProcess serverfault.com user=www-data group=www-data processes=5

Der Host ist ein Linux-Rechner mit 4 GB RAM unter Ubuntu. Kann jemand die Anzahl der Prozesse vorschlagen, die ich oben für meine 2 Aufstellungsorte spezifizieren sollte? Nehmen wir an, sie haben denselben Datenverkehr wie die tatsächlichen Superuser- und Serverfault-Sites.


20
2017-11-03 15:25


Ursprung




Antworten:


Nun, wie viel Verkehr tun die tatsächlichen Superuser und Serverfault Seiten haben? Hypothetische sind nicht sehr nützlich, wenn sie nicht genug Informationen haben, um die Antwort einfacher zu machen ...

Ihre Worst-Case-Prozessanzahl sollte die Spitzenanzahl von Anforderungen pro Sekunde sein, die die Site verarbeiten soll, dividiert durch die Anzahl der Anforderungen pro Sekunde, die ein Prozess verarbeiten kann, wenn alle diese Anforderungen an Ihre langsamste Aktion gestellt werden der Kehrwert der Bearbeitungszeit dieser Aktion). Fügen Sie einen beliebigen Fudge-Faktor hinzu, den Sie für angemessen halten, basierend auf dem Konfidenzintervall Ihrer Messungen von req / sec und time.

Die durchschnittliche Anzahl der Fälle ist die gleiche, aber Sie teilen die req / sec durch das gewichtete Mittel Ihrer Anfragen pro Sekunde für jede Aktion (das Gewicht ist der Prozentsatz der Anfragen, die Sie erwarten, dass diese bestimmte Aktion ausgelöst wird). Auch hier sind Fudge-Faktoren nützlich.

Die tatsächliche Obergrenze für die Anzahl der Prozesse, die Sie auf der Maschine ausführen können, wird von der höheren Speichermenge bestimmt, die jeder Prozess benötigt. Spoolen Sie einen Prozess, führen Sie dann eine Vielzahl von speicherhungrigen Aktionen (die typischerweise viele Daten abrufen und verarbeiten) mit einem realistischen Datensatz aus (wenn Sie nur einen Spielzeugdatensatz zum Testen verwenden, z. B. 50 oder 100) Zeilen, und wenn eine Ihrer Aktionen jede Zeile in der Tabelle aufruft und manipuliert, ist das kein guter Maßstab dafür, wann diese Tabelle auf 10.000 Zeilen anwächst), um zu sehen, wie die Speicherauslastung ansteigt. Sie können die pro-Prozess-Speicherbelegung künstlich einschränken, indem Sie ein Skript verwenden, das Mitarbeiter abruft, die einen bestimmten Speicherauslastungsschwellenwert erreichen. Dies kann zu unangenehmen Problemen führen, wenn Sie diesen Schwellenwert zu niedrig festlegen.

Sobald Sie Ihre Speicherverbrauchszahl haben, ziehen Sie etwas Speicher für den Systemaufwand ab (ich mag selbst 512MB), ziehen einen Stapel mehr ab, wenn Sie andere Prozesse auf demselben Rechner (wie einer Datenbank) ausführen ein paar mehr, um sicherzustellen, dass Sie keinen Speicherplatz im Festplatten-Cache haben (abhängig von der Größe Ihres Festplatten-Working-Sets, aber ich würde wieder mit nicht weniger als 512 MB gehen). Das ist die Menge an Speicher, die Sie durch die Speicherauslastung pro Prozess teilen, um die Obergrenze zu erreichen.

Wenn die Anzahl der Prozesse, die Sie für Ihre Spitzenlast benötigen, größer ist als die Anzahl der Prozesse, die Sie in die Box einbauen können, benötigen Sie mehr Maschinen (oder im einfachsten Fall die Datenbank auf eine andere Maschine verschieben).

Da sind Sie, mehrere Jahre Erfahrung in der Skalierung von Websites in einem kleinen und einfachen SF-Beitrag.


21
2017-11-03 15:44



Ein weiterer wichtiger Faktor für die Anzahl von Prozessen / Threads ist, wie lange einzelne Anfragen bearbeitet werden können und wie sich die gesamte Bandbreite über alle möglichen Zeitspannen erstreckt. Mit anderen Worten, wie viele Anfragen zu einer bestimmten Zeit bearbeitet werden müssen, die eine überdurchschnittliche Antwortzeit benötigen. Es ist also nicht so einfach wie nur theoretische Anfragen pro Sekunde, da die Auswirkungen dieser länger laufenden Anforderungen erheblich sein können und die gesamten Konfigurationsparameter über Gebühr diktieren. FWIW mod_wsgi 3.0 wird einige eingebaute Statistiksammlungen enthalten, um Daten darüber zu sammeln und zu sammeln, um die Konfiguration zu unterstützen. - Graham Dumpleton
@Graham: Lesen Sie meine Antwort, ich habe das ausführlich besprochen. Anfragen / s ist nur der reziproke Wert der Antwortzeit, und es ist einfacher, ihn durch eine ganze Zahl zu teilen, als mit einer Dezimalzahl zu multiplizieren. - womble♦
Sie können sich jedoch nicht nur auf die Worst-Case-Antwort konzentrieren, noch auf den Durchschnittswert. Er muss auf der Grundlage des Prozentsatzes der Anfragen gewichtet werden, die in Zeiträume fallen, dh die Verteilung auf alle möglichen Zeiten. Wenn Sie wirklich Ihre Worst-Case-Reaktionszeit genommen haben, dann würden Sie unrealistische Anforderungen stellen. Das Problem ist es wirklich schwer zu wissen, welche Formel zu verwenden ist. Dies ist der Grund, warum in mod_wsgi 3.0 eingebaute Statistiken gesammelt werden, die sich mit der Thread-Auslastung befassen und nach welchem ​​Prozentsatz nach Anzahl und Zeit eine beliebige Anzahl von Threads gleichzeitig verwendet wird. - Graham Dumpleton
Das Problem ist vielleicht, dass Sie Prozesse nur dann betrachten, wenn ich mir Sorgen darüber mache, wie die Threads jeden Prozess nutzen, und das ist nicht so einfach. Mit anderen Worten, diese WSGIDaemonProcess-Direktive gibt 5 Prozesse an, bei denen jeder Prozess standardmäßig 15 Threads verwendet. So viel ich in Ihrer Beschreibung gelesen habe, geht es von Single-Thread-Prozessen aus. Wenn nicht, weisen Sie mich darauf hin, dass Ihr Modell Probleme mit Threads und Contention / Scaling rund um die GIL bietet. Also, qualifizieren Sie, dass Ihre Beschreibung nur für Single-Thread-Prozesse gültig ist und ich werde nicht streiten. - Graham Dumpleton
Ist der Ansatz "Multithreaded-Apache + multiprocess-wsgi" nicht der beste Weg, bis Sie sich zu 99% sicher sind, dass Ihr Python-Code und alle Abhängigkeiten Thread-sicher sind? - Tomasz Zieliński


wombleDie Antwort ist großartig, wenn auch ein bisschen schwer zu verstehen und für Unerfahrene anzuwenden. Ich möchte einige empirische Zahlen und "einfacher Inhalt" gegenüber "E-Commerce" -Anwendungsvergleich geben.

Es gibt nicht viel Material um verschiedene Anwendungsfälle in Bezug auf die entsprechende Konfiguration von mod_wsgi zu setzen, also hoffe ich, dass es in Ordnung ist, hier ein wenig Prosa zu verwenden.

A) CMS-Seiten und Microsites

Wir betreiben mehrere Kunden-Websites, die meisten von ihnen hauptsächlich Content-Websites oder Micro-Sites Hosting Django CMS, einige benutzerdefinierte Formulare und manchmal Sellerie für geplante Hintergrundaufgaben. Diese Seiten sind nicht ressourcenhungrig, mehrere von ihnen laufen fröhlich parallel auf einem einzigen 4 Core Intel Xeon mit 32 GB RAM. Hier ist die Konfiguration, die wir für jede Art von Websites verwenden:

WSGIDaemonProcess example.com user=www-data processes=2 maximum-requests=100

Ich spreche von ungefähr 40 Sites auf einem einzelnen Server, die meisten davon mit ihrer Staging-Site im Standby-Modus. Mit zwei Prozessen (standardmäßig mit jeweils 15 Threads) sind die Standorte wohlhabend, wenngleich sie nur begrenzt in der Lage sind, Serverressourcen zuzuweisen. Warum diese Konfiguration ausreicht, kann mit der einfachen Natur der (CMS-) Anwendung begründet werden: Es wird nie erwartet, dass eine Anforderung mehr als ein paar Millisekunden dauert. Apache wird immer entspannt bleiben, und das wird auch die CPU-Auslastung sein.

B) E-Commerce-Seiten

Komplexere Sites, die wir ausführen, sind durch immer noch rechnerisch kostengünstige lokale Operationen, aber externe Abhängigkeiten (z. B. Web-Services, die Buchungsdaten bereitstellen) gekennzeichnet, die hinsichtlich der Transaktionszeit teuer sind. Operationen mit externen Anforderungen belegen Threads für viel längere Zeit. Sie benötigen also mehr Threads, um die gleiche Anzahl von Benutzern zu versorgen (im Vergleich zu einer einfachen CMS-Site von oben). Schlimmer noch, Threads werden gelegentlich blockiert, wenn ein externer Service eine Anfrage nicht sofort, manchmal nur für ein paar Sekunden beantworten kann. Dies kann zu dem unangenehmen Nebeneffekt führen, dass Threads, die Anforderungen an die gleiche Dienstwarteschlange stellen, solange warten, bis alle verfügbaren mod_wsgi-Threads aufgebraucht und blockiert sind.

Für diese Szenarien haben wir versucht zu verwenden 6 Prozesse, ohne viel Unterschied zu sehen, und wir landeten mit 12 einen unvergleichlichen Schub in Leistung und Betriebsstabilität zu sehen:

WSGIDaemonProcess example.com user=www-data processes=12 maximum-requests=100

Einige einfache Belastungstests mit 150 und 250 parallelen Benutzern können leicht von der Website gehandhabt werden (während mit 2 Prozesse der Website ist unbrauchbar catering 50 Benutzer parallel). Der 2 CPU 6 Core Intel Xeon mit 32 GB RAM läuft unter dieser Belastung deutlich unter 25% CPU-Auslastung, die RAM-Auslastung bleibt auch bei weniger als 25% nahezu konstant. Beachten Sie, dass wir hier nur für eine einzelne Site eine dedizierte Maschine verwenden, damit wir keine Ressourcen stehlen, die andere Sites benötigen.

Fazit

Die Verwendung einer höheren Anzahl von Prozessen ist ein Kompromiss zwischen der Möglichkeit, dass Apache verfügbare Systemressourcen nutzen kann oder nicht. Wenn Sie ein stabiles Serversystem (keine Website!) Unter "Angriffsbedingungen" behalten wollen, halten Sie die Anzahl niedrig. Wenn Sie möchten, dass Apache Ihnen bei der Verwendung von Systemressourcen (CPU, RAM) hilft, wählen Sie eine höhere Nummer. Wie hoch Sie gehen können, wird in etwa so berechnet, wie es in der oben stehenden Antwort angegeben ist, und wird letztlich durch die verfügbare CPU-Leistung und den verfügbaren Arbeitsspeicher eingeschränkt.

(PS .: Ich behalte die Abschnitt "ConfigurationDirectives" des modwsgi project wiki unter meinem Kopfkissen für Apache-ähnliches Hintergrundlesen. Achten Sie auch darauf, Ihre zu verstehen und zu überwachen Apache-Server offene Verbindungen.)


9
2017-11-14 03:57



Toller Beitrag, aber warum setzt du keine Threadanzahl? Da Pythons GIL viele der Vorteile von Threads negiert, würde ich annehmen, dass Sie mehr Prozesse als Threads haben möchten, aber gibt es einen Vorteil bei der Angabe der Threadanzahl? - Cerin
Die Standardanzahl von threads ist 15 nach der Dokumentation. Ich glaube nicht, dass es einen Vorteil bietet, dies explizit zu spezifizieren. In der Tat, ich erinnere mich daran, es aus einem Grund weggelassen zu haben: Es gab einige Post auf SO oder ein Teil einer Dokumentation, die empfohlen, den Wert wegzulassen, um Nebenwirkungen zu vermeiden (ich weiß, das klingt komisch). Leider finde ich diese Quelle jetzt nicht. Für den Rest Ihrer Frage (GIL) sind Sie wahrscheinlich mehr Experten als ich, tut mir leid. - Peterino
Danke für diese empirische Konfiguration. Beachten Sie jedoch, dass nach dieser Beitrag  You should never use maximum-requests in a production system unless you understand the implications and have a specific temporary need. - raratiru