現在、PHPでジョブキューを実装しようとしています。キューはバッチジョブとして処理され、一部のジョブを並行して処理できるはずです。
私はすでにいくつかの研究を行って、それを実装するいくつかの方法を見つけましたが、それらの長所と短所についてはあまり知りません。
例えば。ここで説明したように、fsockopen
を介してスクリプトを数回呼び出して並列処理を実行します。
PHPでの簡単な並列処理
私が見つけた別の方法は、curl_multi
関数を使用することでした。
curl_multi_exec PHP docs
しかし、これらの2つの方法は、主にバックグラウンドで実行されるキューでバッチ処理を作成するためのオーバーヘッドをかなり追加すると思いますか?
pcntl_fork
についても読みましたが、これも問題を処理する方法のようです。しかし、あなたが何をしているのか本当に分からなければ、それは本当に厄介になる可能性があります(現時点では私のようです;)).
Gearman
も見てきましたが、そこでは、いくつか実行するだけでなく、必要に応じてワーカースレッドを動的に生成し、Gearman Job Serverにそれを無料のワーカーに送信させる必要がありました。特に、1つのジョブが実行された後にスレッドがきれいに終了する必要があるため、最終的にメモリリークが発生することはありません(この問題ではコードが完全ではない場合があります)。
Gearman Getting Started
私の質問は、PHPで並列処理をどのように処理するかです。そして、なぜあなたはあなたの方法を選ぶのですか?異なる方法にはどのような利点/欠点がありますか?
ご意見ありがとうございます。
私はexec()
を使用します。その簡単できれい。基本的に、必要なことを行うスレッドマネージャーとスレッドスクリプトを構築する必要があります。
私はfsockopen()
が好きではありません。なぜなら、サーバー接続を開きます。
同じ理由でcurl
関数が好きではない
pnctl
は好きではありません。pnctl拡張機能が必要であり、親子関係を追跡する必要があるためです。
ギアマンと遊んだことはない...
さて、3つのオプションがあると思います。
A。マルチスレッド:
PHPはマルチスレッドをネイティブにサポートしていません。しかし、pthreads( https://github.com/krakjoe/pthreads )と呼ばれる1つのPHP拡張機能(実験的))があり、これを実行できます。
B。マルチプロセス:
これは、次の3つの方法で実行できます。
C。分散並列処理:
仕組み:
Client
アプリは、データ(別名メッセージ)を「JSON形式にすることができます」エンジン(MQエンジン)「Webサービスのローカルまたは外部にすることができます」に送信しますMQ Engine
データを「主にメモリに、オプションでデータベースに」キュー内に保存します(キュー名を定義できます)Client
アプリは、MQエンジンにデータ(メッセージ)を順番に(FIFOまたは優先度に基づいて)処理するように要求します。「特定のキューからデータを要求することもできます」。いくつかのMQエンジン:
それらの多くはここで見つけることができます: http://queues.io
アプリケーションがunix/linux環境で実行される場合、分岐オプションを選択することをお勧めします。それは基本的に子供がそれを機能させるために遊ぶものです。私はそれをCronマネージャーに使用し、フォークがオプションではない場合にWindowsフレンドリーなコードパスに戻すためのコードを用意しました。
あなたが述べているように、スクリプト全体を数回実行するオプションは、かなりのオーバーヘッドを追加します。スクリプトが小さい場合、問題はないかもしれません。しかし、おそらく、あなたが選択した方法でPHPで並列処理を行うことに慣れるでしょう。そして、次回200MBのデータを使用するジョブがある場合、それは非常に問題になるかもしれません。だから、あなたはあなたが固執できる方法を学ぶ方が良いでしょう。
Gearmanもテストしましたが、とても気に入っています。いくつか考慮すべき点がありますが、全体として、異なる言語で書かれた異なるアプリケーションを実行する異なるサーバーに作品を配布する非常に良い方法を提供します。それを設定することに加えて、実際にPHP内または他の言語からそれを使用することは...もう一度...子どもの遊びです。
あなたが何をする必要があるかについては、それは非常にやり過ぎかもしれません。しかし、データとジョブの処理に関しては、新しい可能性に目が開かれます。そのため、Gearmanを試してみることをお勧めします。
私はPHPのpnctlを使用しています-あなたが何をしているのかを知っている限りそれは良いことです。私はあなたの状況を理解していますが、私たちのコードを理解することは難しいとは思いません。JOBキューまたは並列プロセスを実装するときは、これまで以上に少し意識する必要があります。
あなたがそれを完璧にコーディングし、フローが完全なオフコースであることを確認する限り、実装する際に並列プロセスを念頭に置いておく必要があります。
間違いをする可能性のある場所:
この例をご覧ください- https://github.com/rakesh-sankar/Tools/blob/master/PHP/fork-parallel-process.php 。
それが役に立てば幸い。
私はexec()とギアマンが好きです。 exec()は簡単で、接続がなく、メモリの消費が少ないです。 gearmanにはソケット接続が必要で、ワーカーはいくらかのメモリを使用する必要があります。しかし、gearmanはexec()よりも柔軟で高速です。そして最も重要なのは、ワーカーを他のサーバーに展開できることです。作業が時間とリソースを消費する場合。現在のプロジェクトではギアマンを使用しています。
PHPでの並列処理のいくつかのオプションの概要を以下に示します。
チェックアウト Amp-単純化された非同期並行性 -これは最も成熟しているように見えるPHP並列処理で見たライブラリ。
このクラスは PHPのexec()関数のコメント に投稿され、新しいプロセスをフォークしてそれらを追跡するための本当の簡単な出発点を提供します。
例:
// You may use status(), start(), and stop(). notice that start() method gets called automatically one time.
$process = new Process('ls -al');
// or if you got the pid, however here only the status() metod will work.
$process = new Process();
$process.setPid(my_pid);
// Then you can start/stop/check status of the job.
$process.stop();
$process.start();
if ($process.status()) {
echo "The process is currently running";
} else {
echo "The process is not running.";
}
素晴らしい記事もあります 非同期処理またはPHPのマルチタスク処理 さまざまなアプローチの長所と短所を説明しています:
次に、 (この簡単なチュートリアル もあります。これは Doorman と呼ばれる小さなライブラリにまとめられています。
これらのリンクがより多くの研究の有用な出発点になることを願っています。
「PHPでの簡単な並列処理」で説明されている方法は、実に怖いです-原則はOKです-しかし、実装?既に指摘したように、curl_multi_ fnsはこのアプローチを実装するより良い方法を提供します。
しかし、私はこれらの2つの方法がかなりのオーバーヘッドを追加すると思います
はい、おそらくあなたは仕事を引き渡すためにクライアントとサーバーのHTTPスタックを必要としません-しかし、Googleで働いていない限り、開発時間はハードウェアコストよりもはるかに高価です-HTTPを管理するためのツールがたくさんあります/ analysing performance-ステータス通知や認証などをカバーする定義済みの標準があります。
ソリューションの実装方法の多くは、必要なレベルのトランザクション整合性と、順序どおりの処理が必要かどうかによって異なります。
あなたが言及したアプローチのうち、curl_multi_を使用したHTTPリクエストメソッドに焦点を当てることをお勧めします。しかし、適切なトランザクション制御/順序配信が必要な場合は、メッセージのソースと処理エージェントの間でブローカーデーモンを必ず実行する必要があります(ブローカーのフレームワークとして使用するのに適した、よく書かれたシングルスレッドサーバーがあります ここ )。処理エージェントは一度に1つのメッセージを処理する必要があることに注意してください。
非常にスケーラブルなソリューションが必要な場合は、 RabbitMQ などの適切なメッセージキューシステムを見てください。
HTH
C.