Welches Entwurfsmuster existiert, um die Ausführung einiger PHP-Prozesse und die Sammlung der Ergebnisse in einem PHP-Prozess zu realisieren?
Hintergrund:
Ich habe viele große Bäume (& gt; 10000 Einträge) in PHP und muss rekursive Prüfungen darauf durchführen. Ich möchte die verstrichene Ausführungszeit reduzieren.
Wenn Ihr Ziel minimale Zeit ist - die Lösung ist einfach zu beschreiben, aber nicht so einfach zu implementieren.
Sie müssen ein Muster finden, um die Arbeit zu teilen (Sie liefern in dieser Frage nicht viele Informationen).
Verwenden Sie dann einen Master-Prozess, der Kinder abteilt, um die Arbeit zu erledigen. In der Regel sollte die Gesamtzahl der von Ihnen verwendeten Prozesse zwischen n
und 2n
liegen, wobei n
die Anzahl der Kerne der Maschine ist.
Vorausgesetzt, dass diese Daten in Dateien gespeichert werden, sollten Sie möglicherweise nicht blockierende E / A-Vorgänge verwenden, um den Durchsatz zu maximieren. Wenn Sie dies nicht tun, müssen Sie die meiste Zeit auf die Festplatte warten. PHP hat stream_select()
, das Ihnen helfen könnte. Beachten Sie, dass die Verwendung nicht trivial ist.
Wenn Sie sich entschließen, select
nicht zu verwenden, kann es hilfreich sein, die Anzahl der Prozesse zu erhöhen.
In Bezug auf pcntl
functions: Ich habe einen Deamon mit ihnen geschrieben (einen richtigen mit Forking, Ändern der Session ID, des laufenden Benutzers, etc ...) und es ist eine der zuverlässigsten Software habe geschrieben. Da es für jede Aufgabe Mitarbeiter hervorbringt, selbst wenn es einen Fehler in einer der Aufgaben gibt, wirkt sich dies nicht auf die anderen aus.
Von Ihrem PHP-Skript aus könnten Sie ein weiteres Skript starten (mit exec
), um die Verarbeitung durchzuführen. Speichern Sie Statusaktualisierungen in einer Textdatei, die dann regelmäßig vom übergeordneten Thread gelesen werden konnte.
Hinweis: Um zu vermeiden, dass PHP auf das Skript exec
'd wartet, leiten Sie die Ausgabe in eine Datei:
Alternativ können Sie ein Skript mithilfe der PCNTL erstellen Funktionen. Dies verwendet ein PHP-Skript, das bei der Verzweigung erkennen kann, ob es das Eltern- oder das Kind-Kind ist und entsprechend arbeitet. Es gibt Funktionen zum Senden / Empfangen von Signalen zum Zweck der Kommunikation zwischen Eltern / Kind, oder Sie lassen das Kind sich in eine Datei einloggen und das Elternteil liest aus dieser Datei.
Aus der pcntl_fork Manualseite:
%Vor%Dies ist möglicherweise ein guter Zeitpunkt, um eine Nachrichtenwarteschlange zu verwenden, selbst wenn Sie alles auf einem Computer ausführen.
Sie könnten eine effizientere Datenstruktur verwenden, z. B. einen btree. Ich habe einmal in Java aber nicht in PHP verwendet. Sie können dieses Skript versuchen: Ссылка , es ist eine Implementierung von btree.
Wenn es nicht genug ist, können Sie Hadoop verwenden, um ein Map / Reduce-Muster zu implementieren, wie Michael sagte. Ich würde PHP-Prozess nicht abzweigen, es scheint nicht für die Leistung zu helfen.
Persönlich würde ich PHP als Client verwenden und alles in Hadoop ablegen. Dieses Tutorial könnte helfen: Ссылка .
Eine andere Lösung kann die Verwendung einer Java-Implementierung von Btree sein: Ссылка . JDBM ist eine Objektdatenbank, die eine Btree + Datenstruktur verwendet. Dann können Sie mit PHP suchen, indem Sie Daten mit einem Web-Service verfügbar machen oder indem Sie direkt mit Quercus darauf zugreifen
Die Frage scheint ein wenig verwirrt zu sein.
Ich möchte die absolute Ausführungszeit reduzieren.
Meinst du die verstrichene Zeit? Die Verwendung der richtigen Datenstruktur wird zwar den Durchsatz verbessern, aber für eine gegebene Datenstruktur ist die minimale Reihenfolge des Algorithmus absolut und hat nichts damit zu tun, wie Sie den Algorithmus implementieren.
Welches Designmuster existiert um zu realisieren ....?
Design Patterns sind etwas, was Code ist , keine Vorlage zum Schreiben von Programmen und ein nützliches Werkzeug für den Lehrplanentwurf. Um mit einem Muster zu beginnen und Ihren Code anzupassen, ist es selbst ein Anti-Pattern.
Niemand kann diese Frage beantworten, ohne viel mehr über Ihre Daten und deren Strukturierung zu wissen, aber der Schlüssel für die Effizienz ist die Datenstruktur, die Sie zur Implementierung Ihres Baumes verwenden. Wenn die verstrichene Zeit wichtig ist, dann schauen Sie sich die parallele Ausführung an, aber es lohnt sich auch, die Operation in einem anderen Tool durchzuführen - Datenbanken sind für den Umgang mit großen Datenmengen optimiert, beachten Sie jedoch die offensichtliche Methode zur Beschreibung eines Baumes in Eine relationale Datenbank ist sehr ineffizient, wenn es darum geht, Unterbäume zu isolieren und den Baum zu durchlaufen.
Als Antwort auf Adams Vorschlag, dich zu forken, antwortest du:
Ich habe "gehört", dass pcntl keine gute Lösung ist. Irgendwelche Erfahrungen?
Wo hast du das gehört? Zweifellos ist das Abzweigen von einem CGI- oder mod_php-aufgerufenen Skript eine schlechte Idee, aber nichts falsch daran, es von der Befehlszeile aus zu tun. Haben Sie eine Google für lange laufende PHP-Prozesse (seien Sie gewarnt, es gibt eine Menge schlechter Informationen da draußen). Der Code, den Sie schreiben, hängt vom zugrunde liegenden Betriebssystem ab, das Sie nicht angegeben haben.
Ich vermute, dass Sie einen großen Teil Ihrer Leistungsprobleme lösen könnten, indem Sie identifizieren, welche Teile des Baums geprüft werden müssen und nur diese Teile überprüfen UND die Prüfungen auslösen, wenn der Baum aktualisiert wird, oder zumindest die Knoten als " schmutzig '.
Sie könnten diese hilfreich finden:
C.
Verwenden von Web oder CLI?
Wenn Sie Web verwenden, können Sie diesen Teil in Quercus integrieren. Dann könnten Sie die Vorteile von JAVA nutzen Multithreading.
Ich weiß nicht wirklich, wie zuverlässig Quercus ist. Ich würde auch vorschlagen, eine Art Nachrichtenwarteschlange zu verwenden und den Code neu zu gestalten, so dass der Bereich nicht benötigt wird.
Vielleicht könnten Sie den Code in ein Map / Reduce-Muster umwandeln. Sie können dann den PHP-Code in Hadoop ausführen. Dann können Sie die Verarbeitung durch ein paar Maschinen clustern.
Ich weiß nicht, ob es nützlich ist, aber ich stieß auf ein anderes Projekt namens Gearman . Es wird auch verwendet, um PHP-Prozesse zu clustern. Ich denke du kannst das auch mit einem Reduce Script kombinieren, wenn Hadoop nicht so ist, wie du es willst.
Tags und Links multithreading php asynchronous