4

私はCeleryを使用して、作成したCGIアプリケーションからジョブをキューに入れています。私が設定した方法では、Celeryは、またはを設定することにより、各ジョブを一度に1つまたは2つ実行しますCELERYD_CONCURRENCY = 1= 2したがって、プロセッサが混雑したり、メモリ消費によってスラッシュが発生したりすることはありません)。StackOverflowで得たアドバイスのおかげで、キューはうまく機能します。

これらの各ジョブにはかなりの時間がかかりますが(シリアルで約30分)、恥ずかしい並列化が可能です。このため、私はPool.mapそれを分割して並行して作業を行うために使用していました。コマンドラインからはうまく機能し、新しいメニーコアチップを使用して約5分のランタイムを取得しました。

残念ながら、デーモンプロセスがサブプロセスを持つことを許可しないいくつかの制限があり、CGIキュー内で派手な並列化されたコードを実行すると、次のエラーが発生します。

AssertionError:デーモンプロセスに子を含めることは許可されていません

他の人同様の質問をしていることに気づきましたがPool.map、完全に放棄して、より複雑なスレッドコードを作成する必要のない答えを見つけることができません。

ここでの適切な設計の選択は何ですか?Celeryキューを使用してシリアルジョブを簡単に実行できます。キューなしで、はるかに高速な並列化ジョブを実行することもできます。これにどのようにアプローチすればよいですか?また、必要なもの(キューとジョブごとの並列化の両方)を取得することは可能ですか?

私が持っていたいくつかのアイデア(いくつかはかなりハッキーです):

  • Celeryキューに送信されたジョブは、コマンドラインプログラムを呼び出すだけです。そのプログラムは、プールを好きなように使用して、結果の数値とデータをファイルに保存できます(現在と同じように)。
    欠点:ジョブのステータスを確認したり、正常に終了したかどうかを確認したりできません。また、CGIからのシステムコールはセキュリティの問題を引き起こす可能性があります。
  • 明らかに、キューが非常にジョブでいっぱいの場合は、CPUリソースを利用できます(CELERYD_CONCURRENCY = 6程度に設定することにより)。これにより、一度に多くの人が「列の先頭に立つ」ことができます。
    欠点:各ジョブはキューの先頭で多くの時間を費やします。キューがいっぱいでない場合、スピードアップはありません。また、部分的に終了したジョブの多くは、より多くのRAMを使用して、同時にメモリに保存されます。
  • Celeryの@taskを使用して、サブジョブ内で並列化します。次に、CELERYD_CONCURRENCY = 1に設定する代わりに、6に設定します(または、一度にメモリ内で許可したい多くのサブジョブ)。
    欠点:まず第一に、これが「タスク内タスク」の問題をうまく回避できるかどうかはわかりません。ただし、キューの位置の概念が失われる可能性があり、部分的に終了したジョブの多くが一度にメモリに保存される可能性があります。
  • おそらく、Pool.mapを呼び出して、スレッドが非デーモンであることを指定する方法がありますか?または、Pool.mapの代わりに使用できるより軽量なものがありますか?これは、別の開いているStackOverflowの質問で採用されたアプローチに似ています。また、Pool.mapを介して利用する並列化は線形代数に似ており、プロセス間通信はありません(それぞれが独立して実行され、他のユーザーと通信せずに結果を返します)。
  • Celeryを破棄し、multiprocessing.Queueを使用します。次に、使用するすべてのスレッドに同じ「スレッドの深さ」を使用する方法があるかもしれません(つまり、すべてのスレッドが同じプールを使用して、ネストを回避できる可能性があります)。

よろしくお願いします。

4

2 に答える 2

0

必要なのは、ワークフロー管理システム (WFMS) です。

  • タスクの同時実行
  • タスクの依存関係
  • タスクのネスティング

とりわけ。

非常に高いレベルから見ると、WFMS はセロリのようなタスク プールの上にあり、実行準備が整ったタスクをプールに送信します。また、ネストを開き、それに応じてネスト内のタスクをサブミットする役割もあります。

そのためのシステムを開発しました。それはpomsetと呼ばれます。試してみてください。質問があればお気軽にお送りください。

于 2011-10-12T00:25:15.007 に答える
0

Twisted に基づいたマルチプロセスのデーモンをフォークと Gearman ジョブ クエリで通常どおり使用しています。

ギアマンを見てみてください。

于 2011-10-16T12:16:13.987 に答える