Pengantar
PHP memiliki Multi-Threading lengkap dukungan yang dapat Anda manfaatkan sepenuhnya dalam banyak cara. Mampu mendemonstrasikan kemampuan Multi-Threading ini dalam berbagai contoh:
- Bagaimana cara menggunakan multi threading dalam aplikasi PHP
- pcntl menjalankan kode yang sama beberapa kali, diperlukan bantuan
- Meningkatkan efisiensi scraper HTML dengan pcntl_fork()
Penelusuran cepat akan memberikan sumber daya tambahan.
Kategori
1:kueri MySQL
MySQL sepenuhnya multi-utas dan akan menggunakan beberapa CPU, asalkan sistem operasi mendukungnya, Ini juga akan memaksimalkan sumber daya sistem jika dikonfigurasi dengan benar untuk kinerja.
Pengaturan khas di my.ini
yang mempengaruhi kinerja thread adalah :
thread_cache_size = 8
thread_cache_size dapat ditingkatkan untuk meningkatkan kinerja jika Anda memiliki banyak koneksi baru. Biasanya, ini tidak memberikan peningkatan kinerja yang signifikan jika Anda memiliki implementasi thread yang baik. Namun, jika server Anda melihat ratusan koneksi per detik, Anda biasanya harus menyetel thread_cache_size cukup tinggi sehingga sebagian besar koneksi baru menggunakan utas yang di-cache
Jika Anda menggunakan Solaris maka Anda dapat menggunakan
thread_concurrency = 8
thread_concurrency memungkinkan aplikasi memberi petunjuk kepada sistem utas tentang jumlah utas yang diinginkan yang harus dijalankan pada waktu yang sama.
Variabel ini tidak digunakan lagi pada MySQL 5.6.1 dan dihapus di MySQL 5.7. Anda harus menghapus ini dari file konfigurasi MySQL setiap kali Anda melihatnya kecuali untuk Solaris 8 atau sebelumnya.
InnoDB: :
Anda tidak memiliki batasan seperti itu jika Anda menggunakan Innodb memiliki mesin penyimpanan karena mendukung penuh konkurensi utas
innodb_thread_concurrency // Recommended 2 * CPUs + number of disks
Anda juga dapat melihat innodb_read_io_threads
dan innodb_write_io_threads
di mana defaultnya adalah 4
dan dapat ditingkatkan hingga 64
tergantung pada perangkat kerasnya
Lainnya:
Konfigurasi lain yang juga harus dilihat termasuk key_buffer_size
, table_open_cache
, sort_buffer_size
dll. yang semuanya menghasilkan kinerja yang lebih baik
PHP:
Dalam PHP murni, Anda dapat membuat MySQL Worker di mana setiap kueri dieksekusi di utas PHP terpisah
$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
Berikut adalah Contoh Kerja Lengkap SQLWorker
2:Penguraian konten HTML
Jika Anda sudah mengetahui masalahnya, maka akan lebih mudah untuk diselesaikan melalui loop peristiwa, Antrian Pekerjaan, atau menggunakan Utas.
Mengerjakan satu dokumen satu per satu bisa menjadi sangat, sangat proses yang lambat dan menyakitkan. @ka
setelah meretas jalan keluarnya menggunakan ajax untuk memanggil banyak permintaan, Beberapa pikiran kreatif hanya akan melakukan proses menggunakan pcntl_fork
tetapi jika Anda menggunakan windows
maka Anda tidak dapat memanfaatkan pcntl
Dengan pThreads
mendukung sistem windows dan Unix, Anda tidak memiliki batasan seperti itu. Semudah .. Jika Anda perlu mengurai 100 dokumen? Memunculkan 100 Utas ... Sederhana
Pemindaian HTML
// 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);
Keluaran
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
Kelas Digunakan
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');
}
}
}
Eksperimen
Mencoba menguraikan 8,714
file yang memiliki 105,109
link tanpa utas dan lihat berapa lama waktu yang dibutuhkan.
Arsitektur Lebih Baik
Memunculkan terlalu banyak utas yang bukan merupakan hal yang cerdas untuk dilakukan dalam produksi. Pendekatan yang lebih baik adalah menggunakan Pengumpulan
. Memiliki kumpulan definisi Pekerja
lalu tumpuk
dengan Task
Peningkatan Kinerja
Baik, contoh di atas masih bisa diperbaiki. Daripada menunggu sistem untuk memindai semua file dalam satu utas, Anda dapat menggunakan beberapa utas untuk memindai sistem saya untuk mencari file, lalu menumpuk data ke Pekerja untuk diproses
3:Pembaruan indeks pencarian
Ini sudah cukup banyak dijawab oleh jawaban pertama, tetapi ada banyak cara untuk peningkatan kinerja. Pernahkah Anda mempertimbangkan pendekatan berbasis acara?
Memperkenalkan Acara
@rdlowrey Kutipan 1:
@rdlowrey Kutipan 2 :
Mengapa Anda tidak bereksperimen dengan event-driven
, non-blocking I/O
pendekatan untuk masalah Anda. PHP memiliki libevent
untuk melengkapi aplikasi Anda.
Saya tahu pertanyaan ini semuanya Multi-Threading
tetapi jika Anda punya waktu, Anda dapat melihat Reaktor Nuklir yang ditulis dalam PHP
oleh @igorw
Akhirnya
Pertimbangan
Saya pikir Anda harus mempertimbangkan untuk menggunakan Cache
dan Job Queue
untuk beberapa tugas Anda. Anda dapat dengan mudah mendapatkan pesan yang mengatakan
Document uploaded for processing ..... 5% - Done
Kemudian lakukan semua tugas yang membuang waktu di latar belakang. Silakan lihat Memperkecil tugas pemrosesan besar untuk studi kasus serupa.
Pembuatan Profil
Alat Profil? Tidak ada alat profil tunggal untuk aplikasi web dari Xdebug ke Yslow semuanya sangat berguna. Misalnya. Xdebug tidak berguna dalam hal utas karena tidak didukung
Saya tidak punya favorit