はじめに
PHPには完全な
クイック検索 追加のリソースを提供します。
カテゴリ
1:MySQLクエリ
MySQLは完全にマルチスレッド また、オペレーティングシステムが複数のCPUをサポートしている場合は、複数のCPUを使用します。また、パフォーマンスを適切に構成すると、システムリソースが最大化されます。
my.ini
の一般的な設定 スレッドのパフォーマンスに影響を与えるのは:
thread_cache_size = 8
thread_cache_size 新しい接続がたくさんある場合は、パフォーマンスを向上させるために増やすことができます。通常、適切なスレッド実装がある場合、これによってパフォーマンスが大幅に向上することはありません。ただし、サーバーが1秒間に数百の接続を検出する場合は、通常、ほとんどの新しい接続がキャッシュされたスレッドを使用するように、thread_cache_sizeを十分に高く設定する必要があります
Solaris を使用している場合 その後、
を使用できますthread_concurrency = 8
thread_concurrency アプリケーションがスレッドシステムに、同時に実行する必要のあるスレッドの希望数に関するヒントを提供できるようにします。
この変数はMySQL5.6.1で非推奨になり、MySQL5.7で削除されました。 Solaris 8以前の場合を除いて、MySQL構成ファイルを表示するたびにこれを削除する必要があります。
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では、各クエリが別々のPHPスレッドで実行されるMySQLワーカーを作成できます
$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
2:HTMLコンテンツの解析
すでに問題を知っている場合は、イベントループ、ジョブキュー、またはスレッドを使用して簡単に解決できます。
一度に1つのドキュメントで作業することは、非常に可能です。 遅くて痛みを伴うプロセス。 @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
を使用
パフォーマンスの向上
いいでしょう、上記の例はまだ改善できます。システムが単一のスレッドですべてのファイルをスキャンするのを待つ代わりに、複数のスレッドを使用してシステムでファイルをスキャンし、データをワーカーにスタックして処理することができます
3:検索インデックスの更新
これは最初の回答でほぼ回答されていますが、パフォーマンスを向上させる方法はたくさんあります。イベントベースのアプローチを検討したことがありますか?
イベントの紹介
@rdlowrey 引用1:
@rdlowrey 引用2:
event-driven
を試してみませんか 、non-blocking I/O
あなたの問題へのアプローチ。 PHPには
私はこの質問がすべてMulti-Threading
であることを知っています ただし、時間があれば、このPHPで記述されたNuclearReactor
を見ることができます。 @igorw
最後に
考慮事項
Cache
の使用を検討する必要があると思います およびJob Queue
あなたの仕事のいくつかのために。簡単にメッセージを送ることができます
Document uploaded for processing ..... 5% - Done
次に、バックグラウンドですべての時間を無駄にするタスクを実行します。 大規模な処理ジョブを小さくするをご覧ください 同様のケーススタディについて。
プロファイリング
プロファイリングツール? Xdebug のWebアプリケーション用の単一のプロファイルツールはありません。 Yslow へ すべて非常に便利です。例えば。 Xdebugはサポートされていないため、スレッドに関しては役に立ちません
お気に入りはありません