49

現在、php でジョブ キューを実装しようとしています。その後、キューはバッチ ジョブとして処理され、いくつかのジョブを並行して処理できるようになります。

私はすでにいくつかの調査を行い、それを実装するいくつかの方法を見つけましたが、それらの長所と短所を実際には認識していません.

fsockopenたとえば、ここで説明されているように、スクリプトを数回呼び出して並列処理を行う:
PHP での簡単な並列処理

私が見つけた別の方法は、curl_multi関数を使用することでした。
curl_multi_exec PHP ドキュメント

しかし、これらの 2 つの方法は、主にバックグラウンドで実行する必要があるキューでバッチ処理を作成するためにかなりのオーバーヘッドを追加すると思いますか?

pcntl_forkまた、問題を処理する方法と思われるものについても読みました。しかし、自分が何をしているのかを本当に理解していないと、非常に厄介になる可能性があるようです (現時点での私のように)。

も見ましたGearmanが、必要に応じてワーカー スレッドを動的に生成する必要があり、いくつかを実行して Gearman ジョブ サーバーにそれをフリー ワーカーに送信させるだけではありませんでした。特に、最終的なメモリ リークが発生しないように、1 つのジョブが実行された後にスレッドを正常に終了する必要があるためです (コードはその問題で完全ではない可能性があります)。
Gearman はじめに

私の質問は、PHP で並列処理をどのように処理するのですか? そして、なぜあなたの方法を選択するのですか?異なる方法にはどのような利点/欠点がありますか?

4

9 に答える 9

22

私は使用しますexec()。その簡単できれい。基本的に、必要なことを実行するスレッド マネージャーとスレッド スクリプトを作成する必要があります。

fsockopen()サーバー接続が開かれ、それが構築され、Apacheの接続制限に達する可能性があるため、私は好きではありません

curl同じ理由で関数が嫌い

pnctlpnctl 拡張機能が必要であり、親子関係を追跡する必要があるため、私は好きではありません。

ギアマンと遊んだことない…

于 2011-05-24T08:19:46.410 に答える
4

アプリケーションを unix/linux 環境で実行する場合は、フォーク オプションを使用することをお勧めします。基本的に、それを機能させるのは子供の遊びです。私はそれをCronマネージャーに使用し、フォークがオプションでない場合にWindowsフレンドリーなコードパスに戻すためのコードを持っていました.

あなたが述べたように、スクリプト全体を数回実行するオプションは、かなりのオーバーヘッドを追加します。スクリプトが小さい場合は、問題にならない可能性があります。しかし、選択した方法で PHP で並列処理を行うことにおそらく慣れるでしょう。次回、200 MB のデータを使用するジョブが発生した場合、問題になる可能性があります。ですから、自分が続けられる方法を学んだほうがよいでしょう。

Gearman もテストしましたが、とても気に入っています。考慮すべき点がいくつかありますが、全体として、さまざまな言語で記述されたさまざまなアプリケーションを実行するさまざまなサーバーに作品を配布するための非常に優れた方法を提供します。設定するだけでなく、実際に PHP やその他の言語から実際に使用することは、... 繰り返しになりますが、子供の遊びです。

あなたがしなければならないことに対して、それはやり過ぎかもしれません。しかし、データやジョブの処理に関しては新しい可能性に目を向けることができるので、その点だけでも Gearman を試してみることをお勧めします。

于 2011-05-24T10:20:07.440 に答える
2

私は PHP の pnctl を使用しています。状況は理解できますが、私たちのコードを理解するのは難しいことではないと思います。JOB キューや並列処理を実装する際には、これまで以上に意識する必要があります。

あなたがそれを完璧にコーディングし、フローがコース外で完璧であることを確認している限り、実装するときは並列プロセスを念頭に置いておく必要があると思います.

どこで間違いを犯す可能性がありますか:

  1. ループ - GLOBAL 変数で処理できる必要があります。
  2. 一連のトランザクションの処理 - 繰り返しますが、セットを適切に定義している限り、それを実行できるはずです。

この例を見てください - https://github.com/rakesh-sankar/Tools/blob/master/PHP/fork-parallel-process.php

それが役に立てば幸い。

于 2011-05-24T10:30:48.843 に答える
2

私は exec() と Gearman の方が好きです。exec() は簡単で、接続がなく、メモリ消費が少なくなります。ギアマンにはソケット接続が必要で、ワーカーにはメモリが必要です。しかし、ギアマンは exec() よりも柔軟で高速です。そして最も重要なことは、ワーカーを他のサーバーにデプロイできることです。作業に時間とリソースがかかる場合。現在のプロジェクトでギアマンを使用しています。

于 2011-05-24T10:09:22.987 に答える
1

「PHPで簡単に並列処理」に書かれている方法は、原理はOKですが、実装がなんとも怖いですよね?すでに指摘したように、curl_multi_ fns は、このアプローチを実装するためのはるかに優れた方法を提供します。

しかし、これら2つの方法はかなりのオーバーヘッドを追加すると思います

はい、仕事を引き継ぐためにクライアントとサーバーの HTTP スタックはおそらく必要ありません。ただし、Google で働いている場合を除き、開発時間はハードウェアのコストよりもはるかに高くなります。HTTP を管理するためのツールはたくさんあります。 /パフォーマンスの分析 - ステータス通知や認証などをカバーする定義済みの標準があります。

ソリューションの実装方法の多くは、必要なトランザクション整合性のレベルと、順序どおりの処理が必要かどうかによって異なります。

あなたが言及したアプローチのうち、curl_multi_を使用したHTTPリクエストメソッドに焦点を当てることをお勧めします. しかし、適切なトランザクション制御/配信が必要な場合は、メッセージのソースと処理エージェントの間でブローカー デーモンを実行する必要があります (ここには、ブローカーのフレームワークとして使用するのに適した、適切に作成されたシングル スレッド サーバーがあります)。処理エージェントは一度に 1 つのメッセージを処理する必要があることに注意してください。

高度にスケーラブルなソリューションが必要な場合は、RabbitMQなどの適切なメッセージ キューイング システムを検討してください。

HTH

C.

于 2011-05-24T10:39:47.307 に答える