Einführung
PHP hat volles Multi-Threading Unterstützung, von der Sie in vielerlei Hinsicht profitieren können. Konnten diese Multi-Threading-Fähigkeit in verschiedenen Beispielen demonstrieren:
- Wie kann man Multi-Threading in PHP-Anwendungen verwenden
- pcntl führt denselben Code mehrmals aus, Unterstützung erforderlich
- Verbesserung der HTML-Scraper-Effizienz mit pcntl_fork()
Eine Schnellsuche würde zusätzliche Ressourcen geben.
Kategorien
1:MySQL-Abfragen
MySQL ist vollständig Multithreading und nutzt mehrere CPUs, vorausgesetzt, das Betriebssystem unterstützt sie. Es würde auch die Systemressourcen maximieren, wenn es für die Leistung richtig konfiguriert ist.
Eine typische Einstellung in der my.ini
die die Thread-Leistung beeinflussen, ist :
thread_cache_size = 8
thread_cache_size kann erhöht werden, um die Leistung zu verbessern, wenn Sie viele neue Verbindungen haben. Normalerweise bietet dies keine nennenswerte Leistungsverbesserung, wenn Sie über eine gute Thread-Implementierung verfügen. Wenn Ihr Server jedoch Hunderte von Verbindungen pro Sekunde sieht, sollten Sie thread_cache_size normalerweise hoch genug setzen, damit die meisten neuen Verbindungen zwischengespeicherte Threads verwenden
Wenn Sie Solaris verwenden dann können Sie
verwendenthread_concurrency = 8
thread_concurrency ermöglicht es Anwendungen, dem Thread-System einen Hinweis auf die gewünschte Anzahl von Threads zu geben, die gleichzeitig ausgeführt werden sollen.
Diese Variable ist ab MySQL 5.6.1 veraltet und wurde in MySQL 5.7 entfernt. Sie sollten dies immer dann aus den MySQL-Konfigurationsdateien entfernen, wenn Sie es sehen, es sei denn, sie gelten für Solaris 8 oder früher.
InnoDB: :
Sie haben solche Einschränkungen nicht, wenn Sie verwenden Innodb hat die Speicher-Engine, weil sie Thread-Parallelität vollständig unterstützt
innodb_thread_concurrency // Recommended 2 * CPUs + number of disks
Sie können sich auch innodb_read_io_threads
ansehen und innodb_write_io_threads
wobei der Standardwert 4
ist und kann auf bis zu 64
erhöht werden abhängig von der Hardware
Andere:
Andere Konfigurationen, die Sie sich ebenfalls ansehen sollten, sind key_buffer_size
, table_open_cache
, sort_buffer_size
usw., die alle zu einer besseren Leistung führen
PHP:
In reinem PHP können Sie MySQL Worker erstellen, in dem jede Abfrage in separaten PHP-Threads ausgeführt wird
$sql = new SQLWorker($host, $user, $pass, $db);
$sql->start();
$sql->stack($q1 = new SQLQuery("One long Query"));
$sql->stack($q2 = new SQLQuery("Another long Query"));
$q1->wait();
$q2->wait();
// Do Something Useful
Hier ist ein voll funktionsfähiges Beispiel für SQLWorker
2:HTML-Content-Parsing
Wenn Sie das Problem bereits kennen, ist es einfacher, es über Ereignisschleifen, Jobwarteschlangen oder die Verwendung von Threads zu lösen.
Die Arbeit an einem Dokument nach dem anderen kann sehr, sehr sein langsamer, schmerzhafter Prozess. @ka
Nachdem er sich mit Ajax heraus gehackt hatte, um mehrere Anfragen aufzurufen, teilten einige kreative Köpfe den Prozess einfach mit pcntl_fork
aber wenn Sie windows
verwenden dann können Sie pcntl
nicht nutzen
Mit pThreads
unterstützt sowohl Windows- als auch Unix-Systeme, Sie haben keine solche Einschränkung. Ist so einfach wie .. Wenn Sie 100 Dokumente analysieren müssen? 100 Threads erzeugen ... Einfach
HTML-Scanning
// Scan my System
$dir = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$dir = new RecursiveIteratorIterator($dir);
// Allowed Extension
$ext = array(
"html",
"htm"
);
// Threads Array
$ts = array();
// Simple Storage
$s = new Sink();
// Start Timer
$time = microtime(true);
$count = 0;
// Parse All HTML
foreach($dir as $html) {
if ($html->isFile() && in_array($html->getExtension(), $ext)) {
$count ++;
$ts[] = new LinkParser("$html", $s);
}
}
// Wait for all Threads to finish
foreach($ts as $t) {
$t->join();
}
// Put The Output
printf("Total Files:\t\t%s \n", number_format($count, 0));
printf("Total Links:\t\t%s \n", number_format($t = count($s), 0));
printf("Finished:\t\t%0.4f sec \n", $tm = microtime(true) - $time);
printf("AvgSpeed:\t\t%0.4f sec per file\n", $tm / $t);
printf("File P/S:\t\t%d file per sec\n", $count / $tm);
printf("Link P/S:\t\t%d links per sec\n", $t / $tm);
Ausgabe
Total Files: 8,714
Total Links: 105,109
Finished: 108.3460 sec
AvgSpeed: 0.0010 sec per file
File P/S: 80 file per sec
Link P/S: 907 links per sec
Verwendete Klasse
Sink
class Sink extends Stackable {
public function run() {
}
}
LinkParser
class LinkParser extends Thread {
public function __construct($file, $sink) {
$this->file = $file;
$this->sink = $sink;
$this->start();
}
public function run() {
$dom = new DOMDocument();
@$dom->loadHTML(file_get_contents($this->file));
foreach($dom->getElementsByTagName('a') as $links) {
$this->sink[] = $links->getAttribute('href');
}
}
}
Experimentieren
Versuch, 8,714
zu parsen Dateien mit 105,109
Links ohne Threads und sehen, wie lange es dauern würde.
Bessere Architektur
Zu viele Threads erzeugen, was in der Produktion nicht klug ist. Ein besserer Ansatz wäre die Verwendung von Pooling
. Haben Sie einen Pool von definierten Arbeitern
dann stack
mit einer Task
Leistungsverbesserung
Gut, das obige Beispiel kann noch verbessert werden. Anstatt darauf zu warten, dass das System alle Dateien in einem einzigen Thread scannt, können Sie mehrere Threads verwenden, um mein System nach Dateien zu scannen, und die Daten dann zur Verarbeitung in Workers stapeln
3:Aktualisierung des Suchindex
Dies wurde mit der ersten Antwort ziemlich genau beantwortet, aber es gibt so viele Möglichkeiten zur Leistungsverbesserung. Haben Sie jemals einen ereignisbasierten Ansatz in Erwägung gezogen?
Einführungsveranstaltung
@rdlowrey Zitat 1:
@rdlowrey Zitat 2:
Warum experimentieren Sie nicht mit event-driven
, non-blocking I/O
Herangehensweise an dein Problem. PHP hat libevent
um Ihre Bewerbung aufzuladen.
Ich weiß, dass diese Frage alles Multi-Threading
ist aber wenn Sie etwas Zeit haben, können Sie sich diesen Nuclear Reactor in PHP geschrieben
ansehen von @igorw
Endlich
Gegenleistung
Ich denke, Sie sollten die Verwendung von Cache
in Betracht ziehen und Job Queue
für einige Ihrer Aufgaben. Sie können ganz einfach eine Nachricht mit folgendem Inhalt haben:
Document uploaded for processing ..... 5% - Done
Erledige dann all die zeitraubenden Aufgaben im Hintergrund. Bitte schauen Sie sich Einen großen Verarbeitungsauftrag verkleinern an für eine ähnliche Fallstudie.
Profilerstellung
Profiling-Tool? Es gibt kein einzelnes Profiltool für eine Webanwendung von Xdebug zu Yslow sind alle sehr nützlich. Z.B. Xdebug ist nicht nützlich, wenn es um Threads geht, da es nicht unterstützt wird
Ich habe keinen Favoriten