3

私は、いくつかのパラメータ(AとB)を取り、いくつかの結果を計算する(グラフでAからBへの最適なパスを見つけ、グラフは読み取り専用です)Python(まあ、今はphpですが、書き直しています)関数を持っています一般的なシナリオでは、1 回の呼び出しが完了するまでに 0.1 秒から 0.9 秒かかります。この関数は、単純な REST Web サービス (GET bestpath.php?from=A&to=B) としてユーザーによってアクセスされます。現在の実装は非常にばかげています - これは単純な php スクリプト + apache + mod_php + APC であり、すべてのリクエストですべてのデータ (php 配列で 12MB 以上) をロードし、すべての構造を作成し、パスを計算して終了する必要があります。変えたい。

N 個の独立したワーカー (サーバーごとに Y サーバーの X) を使用したセットアップが必要です。各ワーカーは、ループ (要求の取得 -> 処理 -> 返信の送信 -> 要求の取得...) で実行される Python アプリであり、各ワーカーは処理できます。一度に 1 つの要求。フロントエンドとして機能するものが必要です。ユーザーからリクエストを取得し、リクエストのキューを管理し (構成可能なタイムアウトで)、ワーカーに一度に 1 つのリクエストを供給します。

これにアプローチする方法は?セットアップを提案できますか?nginx + fcgi または wsgi または何か他のもの? ハプロキシ?ご覧のとおり、私は Python やリバース プロキシなどの初心者です。アーキテクチャ (およびデータ フロー) についての出発点が必要なだけです。

ところで。ワーカーは読み取り専用データを使用しているため、ワーカー間のロックと通信を維持する必要はありません

4

7 に答える 7

2

「ワーカー」を個別のプロセスにする必要があるようです(少なくともそれらの一部であるため、複数のプロセスに分割されたスレッドの束ではなく、すべてを個別のプロセスにすることもできます)。Python 2.6 以降の標準ライブラリのmultiprocessingモジュールは、プロセスのプールを生成し、FIFO の「キュー」を介してそれらと通信するための優れた機能を提供します。何らかの理由で Python 2.5 またはそれ以前に行き詰まっている場合は、PyPi リポジトリにマルチプロセッシングのバージョンがあり、ダウンロードして古いバージョンの Python で使用できます。

multiprocessing「フロントエンド」は、WSGI (Apache または Nginx のいずれか) で実行するように非常に簡単に作成できます。また、HTTP やプロキシなどを使用する必要なく、ワーカー プロセスとの間のすべての通信を処理できます。システムの一部。フロントエンドだけがそれ自体が Web アプリになり、ワーカーはフロントエンドから要求された作業単位を受け取り、処理し、応答するだけです。これは、私にとって最も健全でシンプルなアーキテクチャのように思えます。

Python 用のサードパーティ パッケージで利用可能な他の分散処理アプローチがありますが、マルチプロセッシングは非常に適切であり、標準ライブラリの一部であるという利点があるため、他の特有の制限や制約がなければ、マルチプロセッシングをお勧めします。 .

于 2009-11-04T16:05:36.707 に答える
1

Python 用の preforked モードと WSGI インターフェイスを備えた FastCGI モジュールは数多くありますが、最もよく知られているのはflup. このようなタスクに対する私の個人的な好みはsuperfcgi、nginx を使用することです。どちらもいくつかのプロセスを起動し、それらにリクエストをディスパッチします。12Mb は、各プロセスで個別にロードするにはそれほど多くありませんが、ワーカー間でデータを共有したい場合は、プロセスではなくスレッドが必要です。単一のプロセスと多くのスレッドを使用した Python の重い計算は、GIL のために複数の CPU/コアを効率的に使用しないことに注意してください。おそらく最良の方法は、複数のスレッドを実行する複数のプロセス (コアと同じ数) を使用することです ( のデフォルト モードsuperfcgi)。

于 2009-11-05T15:43:09.343 に答える
1

この場合の最も簡単な解決策は、Web サーバーを使用してすべての面倒な作業を行うことです。Web サーバーがすべて処理してくれるのに、なぜスレッドやプロセスを処理する必要があるのでしょうか?

Python の展開における標準的な配置は次のとおりです。

  1. Web サーバーは多数のプロセスを開始し、それぞれが完全な Python インタープリターを実行し、すべてのデータをメモリにロードします。
  2. HTTP リクエストが着信し、何らかのプロセスにディスパッチされます
  3. プロセスは計算を行い、結果を Web サーバーとユーザーに直接返します。
  4. コードまたはグラフ データを変更する必要がある場合は、Web サーバーを再起動して手順 1 に戻ります。

これは、Django やその他の一般的な Web フレームワークで使用されるアーキテクチャです。

于 2009-11-05T19:09:37.747 に答える
1

Python でスレッドを使用してこの種の配置を処理する一般的な方法は、標準ライブラリ モジュールQueueを使用することです。キュー モジュールを使用してワーカーを管理する例は、次の場所にあります:キューの例

于 2009-11-04T16:04:49.877 に答える
0

nginxロードバランサーを使用してPythonPasteパスター(WSGI、たとえばPylonsにサービスを提供)にプロキシすることができます。PythonPasteパスターは、とにかく各リクエストを個別のスレッドとして起動します。

于 2009-11-04T19:39:24.437 に答える
0

もう1つのオプションは、データベース内のキューテーブルです。
ワーカープロセスはループまたはオフcronで実行され、キューテーブルをポーリングして新しいジョブを探します。

于 2009-11-11T21:23:51.987 に答える
0

modwsgi / Apacheを構成して、別々のプロセスで複数の「ホット」なPythonインタープリターをいつでも使用できるようにし、それらを新しいアクセスに再利用できるようにすることができると思います(すべてビジーの場合は新しいインタープリターを生成します)。この場合、すべての前処理されたデータをモジュールグローバルとしてロードでき、それらはプロセスごとに1回だけロードされ、新しいアクセスごとに再利用されます。実際、これがmodwsgi/Apacheのデフォルト構成ではないかどうかはわかりません。

ここでの主な問題は、多くの「コア」メモリを消費してしまう可能性があることです(ただし、それも問題ではない可能性があります)。単一プロセス/複数スレッド用にmodwsgiを構成することもできると思いますが、その場合、Pythonグローバルインタープリターロック(悪名高いGIL)のために1つのCPUしか使用していない可能性があります。

modwsgiメーリングリストで質問することを恐れないでください-彼らは非常に敏感でフレンドリーです。

于 2009-11-04T18:25:37.253 に答える