はじめに
pthreads
を使わない強い理由があるわけではないのですが、すでにあるPHPのバッチスクリプトであっても、ちょっとした工夫で平行処理できるアイデアがあるので紹介します。
pthreads
については、下記の記事に詳しく書いてあるので参照ください。
- PHPはマルチスレッド化で爆速化できるか? pthreadsの使い方(基礎編) - WPJ
- スレッド処理は慎重に – PHPでのスレッド処理 : 前編 | POSTD
- スレッド処理は慎重に – PHPでのスレッド処理 : 後編 | POSTD
尚、並列(pararell
)処理というと、怒られそうなので、並行(concurrent
)処理という言葉を使っています。
結論
何かしらユニークなIDをパーティショニングして、バッチスクリプトの実行時引数として渡してあげることで処理を分散、平行処理することができます。
サンプル
items
テーブルのid
を3分割して取得し、それに対して何らか処理をするサンプルです。
// /path/to/batch/script.php
// 前処理など、いろいろ省略
list($partitionIndex, $partitionSize) = explode('/', $argv[1] ?? '0/1');
$items = $itemRepository->fetchByPartition($partitionIndex, $partitionSize);
foreach ($items as $item) {
// do something...
}
class ItemRepository
{
public function fetchByPartition($partitionIndex = 0, $partitionSize = 1)
{
$sql = <<<SQL
SELECT * FROM items
WHERE id % {$partitionSize} = {$partitionIndex}
ORDER BY id ASC
LIMIT 1000
;
SQL;
$statement = $this->connection->query($sql);
return $statement->fetchAll();
}
}
$ crontab -e
*/5 * * * * php /path/to/batch/script.php 0/3
*/5 * * * * php /path/to/batch/script.php 1/3
*/5 * * * * php /path/to/batch/script.php 2/3
おわりに
泥臭い方法ではありますが、十分に処理時間を短縮できる方法かと思います。
PHP
に限ったアイデアではないので、Python
など他の言語でも活用していただけると幸いです。
ではでは。