Gibt es einen besseren Weg, um die Ergebnisse einen teueren, Sperrung Python-Prozess über HTTP zu dienen?

StackOverflow https://stackoverflow.com/questions/1929681

  •  20-09-2019
  •  | 
  •  

Frage

Wir haben einen Web-Service, die kleinen, willkürliche Segmente ein festes Inventar von größeren MP3-Dateien dient. Die MP3-Dateien werden on-the-fly durch eine Python-Anwendung generiert. Das Modell ist, stellen Sie eine GET-Anforderung an einen URL angeben als Antwort, welche Segmente Sie wollen, erhalten einen audio/mpeg Stream. Dies ist ein teurer Prozess.

Wir sind mit Nginx als Front-End-Request-Handler. Nginx nimmt Antworten für allgemeine Anfragen von Caching.

Wir versuchen zunächst mit Tornado auf der Back-End-Anforderungen verarbeiten von Nginx. Wie man erwarten würde, hielt die Blockierung MP3-Betrieb Tornado von seiner Sache (asynchrone I / O) zu tun. So gingen wir multithreaded, die das Blockierungsproblem gelöst, und ziemlich gut. Allerdings führte es eine subtile Race-Bedingung (unter realer Last), dass wir nicht in der Lage noch zu diagnostizieren oder zu reproduzieren. Die Race-Bedingung korrumpiert MP3-Ausgabe.

So haben wir beschlossen, unsere Anwendung einzurichten als eine einfache WSGI-Handler hinter Apache / mod_wsgi (noch w / Nginx vorne). Dadurch entfällt die Blockierung Problem und die Race-Bedingung, sondern schafft eine kaskadierende Last (das heißt Apache schafft zu viele processses) auf dem Server unter realen Bedingungen. Wir arbeiten an Tuning Apache / mod_wsgi gerade jetzt, aber immer noch auf einer Trial-and-Error-Phase. (Update:.. Wir haben wieder zu Tornado geschaltet Siehe unten)

Schließlich ist die Frage: fehlt uns etwas? Gibt es eine bessere Art und Weise CPU-teure Ressourcen über HTTP?

dienen

Update: Dank Grahams informierte Artikel, ich bin mir ziemlich sicher, dass dies ein Apache-Tuning-Problem. In der Zwischenzeit Zeit haben wir mit Tornado weg zurück und versuchen, die Daten-Korruption Problem zu beheben.

Für diejenigen, die so schnell waren, um mehr Eisen auf das Problem, Tornado und ein bisschen von Multi-Threading zu werfen (trotz der Datenintegrität Problem durch Threading eingeführt) übernimmt die Last in akzeptabler Weise auf einem kleinen (Single-Core) Amazon EC2-Instanz.

War es hilfreich?

Lösung

Sind Sie machen den Fehler, Embedded-Modus von Apache / mod_wsgi verwenden? Lesen Sie:

http: // blog .dscpl.com.au / 2009/03 / Last-Spitzen-und-übermäßige-Speicher-usage.html

Stellen Sie sicher, Sie Daemon-Modus verwenden, wenn Apache / mod_wsgi verwendet wird.

Andere Tipps

Haben Sie versucht Laichen ? Es ist ein WSGI-Server mit einer flexiblen Auswahl an Modi Threading.

Sie können ein Warteschlangensystem mit AJAX Benachrichtigungsmethoden in Betracht ziehen.

Jedes Mal, wenn es eine Anforderung für teure Ressource ist, und dass Ressourcenbedarf erzeugt werden, fügen Sie diese Anforderung in die Warteschlange (wenn es nicht bereits vorhanden ist). Dieser Vorgang Warteschlangen sollte eine ID eines Objekts zurückgeben, dass Sie seinen Status erhalten abfragen kann.

Als nächstes müssen Sie einen Hintergrunddienst schreiben, die Worker-Threads dreht nach oben. Diese Arbeiter einfach dequeue Antrag, um die Daten zu erzeugen, dann ist die Lage des speichert die Daten im Request-Objekt.

Die Webseite kann auf den Server macht AJAX Anrufe den Fortschritt der Generation, um herauszufinden, und einen Link auf die Datei zu geben, sobald es verfügbar ist.

Dies ist, wie GROSS-Media-Sites Arbeit - diejenigen, die insbesondere mit Video zu tun haben. Es könnte jedoch übertrieben für Ihre MP3-Arbeit sein.

Alternativ , Blick in ein paar Maschinen ausgeführt werden, die Last zu verteilen. Ihre Threads auf Apache noch blocken, aber atleast Sie keine Ressourcen auf dem Web-Server verbrauchen wird.

Bitte definieren "Kaskadierung load", da es keine gemeinsame Bedeutung hat.

Ihr wahrscheinlichste Problem sein wird, wenn Sie zu viele Apache-Prozesse ausgeführt werden.

Für eine Last wie diese, stellen Sie sicher, dass Sie die Prefork mpm verwenden, und stellen Sie sicher, dass Sie sich auf eine geeignete Anzahl von Prozessen zu begrenzen (nicht weniger als eine pro CPU, nicht mehr als zwei).

Es sieht aus wie Sie die Dinge richtig tun - nur CPU-Leistung fehlt: Sie können bestimmen, was die CPU-Belastung in dem Prozess ist, diese MP3 der Erzeugung

ich glaube, das nächste, was Sie tun müssen, gibt es mehr Hardware hinzuzufügen, um die MP3-Dateien auf anderen Maschinen zu machen. Oder das, oder einen Weg finden, vorgerenderten MP3 liefern (vielleicht können Sie einige Ihrer Medien cahce?)

BTW, Skalierung für das Web war das Thema eines Keynote Vortrags von Jacob Kaplan-Moss auf PyCon Brasil in diesem Jahr, und es ist bei weitem nicht ein geschlossenes Problem. Der Stapel von Technologien ein Bedarf Griff ist ziemlich impressible - (ich nicht eine Online-Kopie o f die Präsentation finden konnte, obwohl - -Sorry für das)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top