Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да използвате добре многоядрените процесори във вашите PHP/MySQL приложения?

Въведение

PHP има пълен Multi-Threading подкрепа, от която можете да се възползвате напълно по толкова много начини. Успях да демонстрирам тази способност за многонишковост в различни примери:

бързо търсене ще даде допълнителни ресурси.

Категории

1:MySQL заявки

MySQL е напълно многонишков и ще използва множество процесори, при условие че операционната система ги поддържа. Освен това ще увеличи максимално системните ресурси, ако е правилно конфигуриран за производителност.

Типична настройка в my.ini които влияят върху производителността на нишката е:

thread_cache_size = 8

thread_cache_size може да се увеличи за подобряване на производителността, ако имате много нови връзки. Обикновено това не осигурява значително подобрение на производителността, ако имате добра реализация на нишката. Въпреки това, ако вашият сървър вижда стотици връзки в секунда, обикновено трябва да зададете thread_cache_size достатъчно високо, така че повечето нови връзки да използват кеширани нишки

Ако използвате Solaris след това можете да използвате

thread_concurrency = 8 

thread_concurrency позволява на приложенията да дават на системата нишки намек за желания брой нишки, които трябва да се изпълняват едновременно.

Тази променлива е остаряла от MySQL 5.6.1 и е премахната в MySQL 5.7. Трябва да премахнете това от конфигурационните файлове на MySQL всеки път, когато го видите, освен ако не са за Solaris 8 или по-стара версия.

InnoDB: :

Нямате такива ограничения, ако използвате Innodb има механизма за съхранение, тъй като напълно поддържа паралелност на нишки

innodb_thread_concurrency //  Recommended 2 * CPUs + number of disks

Можете също да разгледате innodb_read_io_threads и innodb_write_io_threads където по подразбиране е 4 и може да се увеличи до 64 в зависимост от хардуера

Други:

Други конфигурации, които също трябва да разгледате, включват key_buffer_size , table_open_cache , sort_buffer_size и т.н., които водят до по-добро представяне

PHP:

В чист PHP можете да създадете MySQL Worker, където всяка заявка се изпълнява в отделни PHP нишки

$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

Ето пълен работен пример за SQLWorker

2:Анализ на HTML съдържание

Ако вече знаете проблема, тогава той улеснява решаването му чрез цикъл на събития, опашка за задания или чрез използване на нишки.

Работата върху един документ един по един може да бъде много, много бавен, болезнен процес. @ka след като хакнат изхода си с помощта на ajax за извикване на множество заявки, някои креативни умове просто биха разклонили процеса, използвайки pcntl_fork но ако използвате windows тогава не можете да се възползвате от pcntl

С pThreads поддържайки както Windows, така и Unix системи, Вие нямате такова ограничение. Лесно ли е като .. Ако трябва да анализирате 100 документа? Създайте 100 нишки ... Просто

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);

Изход

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

Клас Използван

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');
        }
    }
}

Експеримент

Опитвам да анализирам 8,714 файлове, които имат 105,109 връзки без теми и вижте колко време ще отнеме.

По-добра архитектура

Създаване на твърде много нишки, което не е умно нещо в производството. По-добър подход би бил да се използва Обединение . Имайте набор от дефинирани работници след това стек с Task

Подобряване на производителността

Добре, примерът по-горе все още може да бъде подобрен. Вместо да чакате системата да сканира всички файлове в една нишка, можете да използвате няколко нишки, за да сканирате моята система за файлове, след което да подредите данните в Workers за обработка

3:Обновяване на индекса на търсене

Това е почти отговорно от първия отговор, но има толкова много начини за подобряване на производителността. Обмисляли ли сте някога подход, базиран на събития?

Въвеждащо събитие

@rdlowrey Цитат 1:

@rdlowrey Цитат 2:

Защо не експериментирате с event-driven , non-blocking I/O подход към вашия проблем. PHP има libevent за да допълните приложението си.

Знам, че този въпрос е изцяло Multi-Threading но ако имате време, можете да погледнете този ядрен реактор, написан на PHP от @igorw

Най-накрая

Разглеждане

Мисля, че трябва да помислите за използването на Cache и Job Queue за някои от вашите задачи. Можете лесно да получите съобщение, което казва

Document uploaded for processing ..... 5% - Done   

След това правете всички задачи, които губите време във фонов режим. Моля, вижте Намаляване на голяма задача за обработка за подобен казус.

Профилиране

Инструмент за профилиране? Няма инструмент за един профил за уеб приложение от Xdebug до Yslow всички са много полезни. напр. Xdebug не е полезен, когато става въпрос за нишки, защото не се поддържа

Нямам фаворит



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL:Колко място използва полето NULL?

  2. MySQL - броене по месеци (включително липсващи записи)

  3. Как да използвате .htaccess за красиви връзки

  4. JSON кодиране на MySQL резултати

  5. Mysql премахва времевия компонент от datetime