2017-05-12 5 views
1

Celery 4.xを使用してタスクを非同期で実行するDjango webappがあります。主なタスクでは、Django/Celeryコードが20〜100台の他のサーバーとのネットワーク通信操作を実行する必要があります。これらの他のサーバーに送信するリクエストはすべて同じです。つまり、ユーザーはDjangoにコマンドを送信します.Djangoは、Celeryに20-100のサーバーのそれぞれにまったく同じコマンドを送信するよう指示します。問題は、Celeryの基本的な設定では、4人のワーカーがいれば、セラーリーは4人のサーバとしか通信できないということです。この問題を解決するために、私たちはgeventでCeleryを使ってみました。しかし、geventでは、スレッド全体ではなくコルーチンを使用しています。私たちのネットワーク操作では、Cで書かれた独自のPythonモジュールを使用しています。つまり、pythonソケットを使用していません。Django plus Cソケットモジュールのスレッディング付きCelery/RabbitMQ

私たちがしたいことは次のとおりです。議論のために、私たちのCコミュニケーションモジュールが "cnet"と呼ばれているとしましょう。

# This uses our cnet module (written in C) to connect to a single other server 
def connect_to_server(server, user_data): 
    response=cnet.execute_request(server,user_data) 
    output=do_something_with_response(response) 
    return output 

@task 
def send_something_important_to_all_servers(dest_servers, user_data): 
    for server in dest_servers: 
     t = create new thread to run connect_to_server(server, user_data) 
     t.start() 
    wait/join on all threads 
    return 

私たちはこれを実装する方法についての質問の数を持っている:我々はと通信しなければならない20台の他のサーバーを持っている場合は、我々はこのような何かを行うセロリタスク機能を持っているでしょう。最初は作業場プールと複数の作業者を使用しましたが、作業者1人につき1つの作業がありましたが、それは拡張されませんでした。次に、私たちはgeventを使いましたが、何も特別なことはしませんでした。ちょうど4人の労働者がセールを開始しました。ここに行われたのと同じように、多くの野菜をたくさん持っています。https://groups.google.com/forum/?fromgroups=#!topic/celery-users/RNZLiNyykQQ もちろん、 4人の労働者を抱えていた時、私たちは同時に4つのことを実行しました。

これで、イベントレットプールを使用できることを読んだので、タスク内で複数のスレッドを生成するために使用できるtpoolというものがあります。ドキュメントは、これが猿のパッチを当てることができないネイティブのCネットワークモジュールを使用している私たちのような状況に特に有用であると言います。これが私たちにとって最良のアプローチです。つまり、tpoolでeventletを使用していますか?私たちの状況では、イベントレットではなくジントントを使用する理由はありますか?その場合、tpoolと同等の意味合いがありますか?誰かがこのような状況を処理するセロリコードの例を持っていますか?つまり、サルのパッチを当てることができない非ネイティブのネットワーキングコードを使用していますか?

答えて

1

ベスト・オプションは、Cで多重化し、すべての要求を行う単一の機能としてCeleryに提示することです。 Cでこれを行うためのさまざまなアプローチもあります.OSスレッドは1つですが、1つです。あなたが最もよく知っているもの、最も快適なものを選んでください。

イベントレットtpoolは機能しますが、そのサイズはデフォルトでは20であることに注意してください。

Cモジュールの内部からPythonソケットモジュールを使用すると、Monkey patchingは動作します。これはおそらく最も安価で最速の方法です。

更新:eventlet.tpool()収率。ブロッキングAPIはライブラリの目的に反しているため、ドキュメントに明示的に記述されていません。任意の数のコルーチン(tpoolサイズよりも小さいか大きい)が期待どおりに動作します。 Tpoolサイズは、同時に実行されているOSスレッドの数を制限します。

+0

この時点でCで多重化を行うことはできません。非常に複雑なCプログラムではあまりにも多くの作業を行います。そして、私はPythonソケットがCコードで使われていなかったと確信しています。だから、tpoolは行く道だと思う。しかしtpool.executeは、tpool.executeを呼び出すすべてのコルーチンが同時に(最大20個まで)同時に実行できるように、他のコルーチンに与えるような方法でブロックしますか?これはドキュメントでうまく説明されていません。 – Marc

+0

おそらく、Pythonソケットは使用されていないかもしれませんが、検索と置換が容易な変更です。 Tpoolは他のすべてのものとして得ます。 – temoto

+0

対応するモジュールはgeventにありますか? eventlet.tpoolを使用する代わりに、gevent.somethingを使用できますか? – Marc

関連する問題