Heim > Artikel > Backend-Entwicklung > Wie kann die Effizienz verbessert werden, wenn PHP umfangreiche Aufgaben ausführt?
Ich habe ein PHP-Programm, das einmal täglich auszuführende Aufgaben plant:
1. Stellen Sie eine Verbindung zur Datenbank her und wählen Sie aus, ob relevante Daten aus der Datenbank in das Array eingelesen werden sollen.
2. Schleife entsprechend der Anzahl der erhaltenen Daten, in der Mitte der Schleife. Enthält 3 MySQL-Operationen (je eine für Auswählen, Einfügen und Aktualisieren)
3. Schließen Sie die Datenbankverbindung, nachdem die Schleife abgeschlossen ist
Die Anzahl der Schleifenausführungen hängt von den mysql_num_rows in Schritt 1 ab und beträgt grundsätzlich Tausende oder Zehntausende.
Während des Schleifenprozesses werden dann in kurzer Zeit Tausende von X3-Datenbankoperationen kontinuierlich ausgeführt, was sehr ineffizient ist. Und da die Ausführung mehrerer Aufgaben aufgrund der Anzahl der Zyklen lange dauert, tritt in Nginx ein 504-Fehler auf.
Darüber hinaus beanspruchen häufige Datenbankoperationen und lange Verbindungen zu viele Ressourcen, was zu einer Ineffizienz der gesamten Umgebung führt.
Wie kann man es optimieren?
Bitte geben Sie mir einen Rat, vielen Dank im Voraus
Ich habe ein PHP-Programm, das einmal täglich auszuführende Aufgaben plant:
1. Stellen Sie eine Verbindung zur Datenbank her und wählen Sie aus, ob relevante Daten aus der Datenbank in das Array eingelesen werden sollen.
2. Schleife entsprechend der Anzahl der erhaltenen Daten, in der Mitte der Schleife. Enthält 3 MySQL-Operationen (je eine für Auswählen, Einfügen und Aktualisieren)
3. Schließen Sie die Datenbankverbindung, nachdem die Schleife abgeschlossen ist
Die Anzahl der Schleifenausführungen hängt von den mysql_num_rows in Schritt 1 ab und beträgt grundsätzlich Tausende oder Zehntausende.
Während des Schleifenprozesses werden dann in kurzer Zeit Tausende von X3-Datenbankoperationen kontinuierlich ausgeführt, was sehr ineffizient ist. Und da die Ausführung mehrerer Aufgaben aufgrund der Anzahl der Zyklen lange dauert, tritt in Nginx ein 504-Fehler auf.
Darüber hinaus beanspruchen häufige Datenbankoperationen und lange Verbindungen zu viele Ressourcen, was zu einer Ineffizienz der gesamten Umgebung führt.
Wie kann man es optimieren?
Bitte geben Sie mir einen Rat, vielen Dank im Voraus
Was die von Ihnen erwähnte Situation betrifft, wird empfohlen, keine Anfragen zur Lösung des Problems zu verwenden. Verwenden Sie crontab, um geplante Aufgaben hinzuzufügen, um das PHP-Skript im Hintergrund auszuführen, und verarbeiten Sie es in Stapeln, z Insgesamt 100.000 Elemente, 1.000 Elemente gleichzeitig. Wenn die Geschwindigkeit nicht sehr hoch ist, wird empfohlen, sie während fetch_row zu verarbeiten, um zu vermeiden, dass sie zuerst in das Array eingefügt werden und dann wiederholt werden. Denken Sie daran, set_time_limit und das Timeout der Datenbankverbindung basierend auf der Implementierung festzulegen.
Ein paar Gedanken zu dieser Art von Langzeitaufgabe mit einer etwas größeren Datenmenge:
1. Die Webumgebung ist nicht für Langzeitaufgaben geeignet: Die Nginx-PHP-FPM-Architektur ist nicht für Langzeitaufgaben geeignet -Term-Aufgaben, die verschiedenen Zeitüberschreitungen in der Mitte können Menschen zu Tode quälen, Apache PHP ist zumindest besser, um die Zeitüberschreitung zu kontrollieren, ein einfaches set_time_limit (0) kann es tun.
2. Die Aufgabenplanung wird über das Web implementiert: Die meisten PHP-Frameworks verfügen nicht über eine gute Befehlszeilenunterstützung oder berücksichtigen bei der Implementierung keine Befehlszeilenunterstützung, sodass ein webbasierter Aufgabenverteilungsmechanismus einfacher zu implementieren ist. Dies wird das bestehende Framework weniger beeinträchtigen und für ein stabiles Projekt ist es äußerst wichtig, einen einheitlichen Zugang sicherzustellen. Wenn die Aufgabe über die Befehlszeile ausgeführt wird, sind viele Probleme zu berücksichtigen. Das wichtigste Problem ist das Problem mit der Dateiberechtigung. Im Allgemeinen werden Webprojekte von Benutzern wie Apache ausgeführt, und der Eigentümer der generierten Dateien ist ebenfalls Apache. und Apache im Allgemeinen nicht. Obwohl die Anmeldung zulässig ist, ist es möglich, Befehle als Apache-Benutzer auszuführen, dies ist jedoch komplizierter.
3. Teilen und erobern: Eine Lösung für den Umgang mit langfristigen Aufgaben besteht darin, große Aufgaben in kleine Aufgaben aufzuteilen, langfristige Aufgaben in mehrere kurzfristige kleine Aufgaben umzuwandeln und den Zeitaufwand für Ressourcen zu reduzieren. und reduzieren Sie den Zeitaufwand für Ressourcen. Verschiedene Probleme, die durch lange Ausführung verursacht werden, wie z. B. Zeitüberschreitungen bei der Datenbankverbindung, PHP-Speicherlecks usw.
Anbei ist ein Beispiel, das ich geschrieben habe, bitte geben Sie mir einen Rat
https://github.com/zkc226/cur...
Wenn eine große Datenmenge benötigt wird, wird diese zur Ausführung an das Aufgabensystem übergeben. Zuerst wird eine Anfrage initiiert und der Nachrichtenproduzent übergibt die Anfrage an den Konsumenten zur Verarbeitung und Rückgabe, um das Warten auf eine Zeitüberschreitung zu vermeiden. Verbraucher führen eine Multithread-Verarbeitung durch. Es wird empfohlen, Gearman zu verwenden, das sehr benutzerfreundlich ist und die PHP-Schnittstelle unterstützt. Andere wie Workman, Swoole usw. können implementiert werden.
Alle Vorgänge werden zum gleichen Zeitpunkt auf demselben Server ausgeführt, was definitiv zeitaufwändig und ressourcenintensiv ist.
Entweder, wie @黄红 sagte, in Stapeln verarbeiten.
Oder das Hinzufügen von Servern und das Verteilen dieser Aufgaben zur Ausführung auf andere Server wird als verteilte Verarbeitung bezeichnet, erhöht jedoch die Komplexität der Aufgaben, da die Datenkonsistenz sichergestellt werden muss
1. Daten in eine Datei exportieren, die Datei lesen und eine Schleife ausführen. (Zum Beispiel mysqldump)
2. Überlegen Sie, ob Sie die Anweisungen zuerst buchstabieren und dann stapelweise ausführen können. Anstatt jede Schleife auszuführen.
3. Überlegen Sie, ob gespeicherte Prozeduren verwendet werden können
Und aufgrund der Anzahl der Zyklen dauert die Ausführung mehrerer Aufgaben lange, was zu einem 504-Fehler in Nginx führt.
Ist es eine Echtzeitberechnung? Sollten wir bei Aufgaben mit vielen Berechnungen in Betracht ziehen, Hintergrundaufgaben auszuführen, um den Schreibcache zu berechnen und den schreibgeschützten Cache in Echtzeit anzufordern?
Diese Frage ähnelt ein wenig der Frage, die ich zuvor zur parallelen Ausführung zur Verbesserung der Effizienz beantwortet habe
Das Wesentliche besteht darin, das Lesen dieser großen Datenmengen auszulagern und eine modulo-parallele Ausführung basierend auf der ID durchzuführen. Beispielsweise können Ihr Server und Ihre Datenbank 20 gleichzeitigen Ausführungen standhalten
Der einfachste Weg zur Parallelisierung besteht darin, 20 Skriptprozesse zu öffnen, um
0.php -> select * from test where id =0;
1.php -> select * from test where id = 1;
2.php -> select * from test where id =2;
....
Dies ist die Ziehmethode.
Eine andere Möglichkeit besteht darin, es in die Warteschlange zu verschieben, und dann ruft die Warteschlange den Waker-Prozess zur Ausführung auf. Dies ist beispielsweise ein Gearman, der oben erwähnt wurde Plattform, ich hatte auch täglich geplante Aufgaben. Diese verwende ich.
Die Logik besteht wahrscheinlich darin, dass Sie ein geplantes Aufgabenskript öffnen, um alle abgefragten Daten an den Gearman-Scheduler zu senden, indem Sie den Gearman-Client aufrufen, und dann 20 Worker öffnen (können sich auf demselben Server oder innerhalb des lokalen Netzwerks befinden). Verschiedene Server), dann weist der Scheduler diese 20 Gearman-Worker-Skripte zur Ausführung zu. Der Code jedes Worker-Skripts ist derselbe und es handelt sich um die Ausführung eines Datenelements und einer Aufgabe
Verwenden Sie einfach das PHP-Skript im CLI-Modus. Verwenden Sie nicht die WEB-Methode, es kann leicht zu Zeitüberschreitungen kommen