Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bagaimana Anda memanfaatkan CPU multicore dengan baik dalam aplikasi PHP/MySQL Anda?

Pengantar

PHP memiliki Multi-Threading lengkap dukungan yang dapat Anda manfaatkan sepenuhnya dalam banyak cara. Mampu mendemonstrasikan kemampuan Multi-Threading ini dalam berbagai contoh:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa menggunakan now() di Doctrine 2 DQL?

  2. sebar plot di jfreechart dari database

  3. Bagaimana cara membuat paginasi hasil kueri untuk Gulir Tak Terbatas?

  4. Bagaimana cara menyimpan IP di mySQL

  5. mysql mengubah kunci unik menjadi primer (mariadb)