Einzelnen Beitrag anzeigen

Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#2

AW: PHP: Skript parallel starten

  Alt 2. Jul 2011, 09:39
Moin,

um asynchrone Jobs zu starten gibt es mehrere Extensions. Ich bevorzuge hier Gearman, aus ganz einfachen Gruenden:
  • Die Client-Libraries, mit denen Jobs gestartet werden, gibt es fuer viele Programmiersprachen
  • Es ist kein Problem, ueber ein PHP-Script einen Job zu starten, der aber in C, Java oder Python geschrieben ist. Du kannst fuer jeden Teil der Anwendung die beste Sprache auswaehlen.
  • Die Datenuebertragung funktioniert anhand von Strings (genauer gesagt ein String-Parameter, ein String-Return), d.h. du entscheidest selbst wie du die Daten uebertragen willst (z.B. JSON-encodiert)
  • Es gibt eine telnet-Konsole, ueber die du den Status des Gearman ueberwachen kannst

Nachteil ist natuerlich, dass du einerseits ein apt-Paket fuer den Gearman-Server installieren musst sowie eine PECL-Extension (gearman) installieren musst damit alles laeuft. Hier ein Kurzueberblick wie das funktioniert.

Dein Script B, welches asynchron im Hintergrund laeuft, wird als Gearman-Skript registriert. Beim Start meldet es sich bei einem Gearman-Server an und registriert eine oder mehrere Funktionen und hinterlegt dazu eine Callback-Funktion, die dann tatsaechlich ausgefuehrt wird. Anschliessend tritt es in einen busy-waiting-Status und wartet auf Jobs.

Dein Script A sieht dass ein Hintegrundskript ausgefuehrt werden muss und baut ebenfalls eine Verbindung zum Gearman-Server auf. Anschliessend teilst du dem Gearman-Server mit, welche Funktion du ausfuehren willst und gibst ihm noch einen String-Parameter dazu. Du kannst auch entscheiden, ob du das Skript synchron oder asynchron starten willst. Bei der synchronen Ausfuehrung erhaelst du als Rueckgabewert das Ergebnis der in Script B ausgefuehrten Funktion (auch hier wieder nur ein String). Bie der asynchronen Ausfuehrung erhaelst du ein Token als Rueckgabewert, mit dem du den Status des Jobs pruefen kannst.

Damit Script C das Ergebnis am Ende irgendwo abholen kann, muss es einerseits das Token wissen, Script B muss das Ergebnis aber auch irgendwohin schreiben. Der Gearman-Server "vergisst" das naemlich, sobald Script B durch ist. Alternativ koenntest du auch mit Gearman-Tasks arbeiten, damit habe ich aber noch nicht viel gemacht.

Angenommen du hast nun die Scripte geschrieben und stellst fest dass die Ausfuehrung von Script B ueber Gearman lang dauert, weil viele Jobs in der Queue sind. Jede Instanz eines Gearman-Worker kann immer nur einen Job abarbeiten. Erst sobald dieser abgearbeitet ist, kommt der naechste dran. Du kannst aber soviele Instanzen starten wie du willst. Dann geschieht die Ausfuehrung von mehreren Tasks parallel.
Nun waechst die Anwendung weiter und du stellst fest dass der Server auf dem die Gearman-Jobs laufen komplett ausgelastet ist. Du kannst auch hier weiterskalieren und einfach auf einem zweiten Server dasselbe Script x-mal starten und wieder beim selben Gearman-Server registrieren. Dann verteilt der Gearman-Server die Jobs auch auf die beiden Maschinen.
Dieser Gearman-Server benoetigt normalerweise nicht viele Resourcen, aber es kann trotzdem sein dass er ueberlastet ist. Du kannst auch mehrere Instanzen eines Gearman-Servers aufsetzen. Wenn sich die Jobs alle bei allen Servern registrieren und die Clients in Script A sich auch bei allen Servern registrieren wird auch der Management-Teil skaliert. Du kannst diese Loesung also komplett in alle Richtungen skalieren, je nachdem wie du es brauchst.

So, ich hoff dass das halbwegs verstaendlich ist. Die PHP-Doku zur Gearman-Extension gibt dir einen guten Ueberblick ueber die Funktionen sowie ein paar Beispiele, anhand denen du das erstmal testen kannst. Auch die Gearman-Seite selbst stellt ein paar PHP-Beispiele zur Verfuegung.

Greetz
alcaeus
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat