~400 の HTTP GET リクエストを送信して結果を収集しようとしています。私はジャンゴから走っています。私の解決策は、geventでセロリを使用することでした。
セロリ タスクを開始するには、get_reportsを呼び出します。
def get_reports(self, clients, *args, **kw):
sub_tasks = []
for client in clients:
s = self.get_report_task.s(self, client, *args, **kw).set(queue='io_bound')
sub_tasks.append(s)
res = celery.group(*sub_tasks)()
reports = res.get(timeout=30, interval=0.001)
return reports
@celery.task
def get_report_task(self, client, *args, **kw):
report = send_http_request(...)
return report
私は4人の労働者を使います:
manage celery worker -P gevent --concurrency=100 -n a0 -Q io_bound
manage celery worker -P gevent --concurrency=100 -n a1 -Q io_bound
manage celery worker -P gevent --concurrency=100 -n a2 -Q io_bound
manage celery worker -P gevent --concurrency=100 -n a3 -Q io_bound
そして、RabbitMq をブローカーとして使用します。
そして、リクエストを順次実行するよりもはるかに高速に動作しますが (400 リクエストに約 23 秒かかりました)、その時間のほとんどがセロリ自体のオーバーヘッドであることに気付きました。
@celery.task
def get_report_task(self, client, *args, **kw):
return []
この操作全体に約 19 秒かかりました。つまり、すべてのタスクをセロリに送信して結果を返すだけで 19 秒を費やしています。
rabbit mq へのメッセージのキューイング レートは 28 メッセージ/秒に制限されているようで、これが私のボトルネックだと思います。
それが問題になる場合、私はwin 8マシンで実行しています。
私が試したことのいくつか:
- redis をブローカーとして使用する
- 結果のバックエンドとして redis を使用する
それらの設定を微調整する
BROKER_POOL_LIMIT = 500
CELERYD_PREFETCH_MULTIPLIER = 0
CELERYD_MAX_TASKS_PER_CHILD = 100
CELERY_ACKS_LATE = 偽
CELERY_DISABLE_RATE_LIMITS = True
スピードアップに役立つ提案を探しています。