1. ホーム
  2. python

[解決済み] celeryのタスクプリフェッチを理解する

2023-03-08 05:20:12

質問

コンフィギュレーション・オプションの CELERYD_PREFETCH_MULTIPLIER ( ドキュメント ). デフォルトは4ですが、(確か)私はプリフェッチをオフにするか、できるだけ低くしたいのです。今は1にしているので、求めているものに近いのですが、まだわからないことがあります。

  1. なぜこのプリフェッチが良いアイデアなのでしょうか。メッセージキューとワーカーの間に多くのレイテンシーがない限り、その理由はよくわかりません(私の場合、現在同じホストで動作していますが、最悪の場合、同じデータセンター内の異なるホストで動作する可能性があります)。ドキュメントでは、欠点に言及するだけで、利点が何であるかを説明していません。

  2. 多くの人はこれを 0 に設定し、その方法でプリフェッチをオフにできることを期待しているようです(私の意見では、妥当な仮定です)。しかし、0 は無制限のプリフェッチを意味します。なぜ無制限のプリフェッチを望むのでしょうか。それは、そもそもタスクキューを導入した際の同時実行性/非同期性を完全に排除してしまうのではありませんか。

  3. なぜプリフェッチをオフにできないのでしょうか?ほとんどの場合、それをオフにすることはパフォーマンスにとって良いアイデアではないかもしれませんが、これができない技術的な理由があるのでしょうか? あるいは、単に実装されていないだけなのでしょうか?

  4. 時々、このオプションに接続されている CELERY_ACKS_LATE . 例えば Roger Hu さんが書き込みました。 "[...] しばしば[ユーザーが]本当に欲しいものは、子プロセスの数だけワーカーにタスクを予約させることです。しかし、これは遅延承認を有効にしない限り不可能です[...]」 この2つのオプションがどのように関連しているのか、そしてなぜ一方が他方なしでは不可能なのか、私には理解できないのです。この関連性については、次のような記述もあります。 ここで . なぜこの2つのオプションがつながっているのか、どなたか説明してください。

どのように解決するのですか?

  1. プリフェッチは、パフォーマンスを向上させることができます。ワーカーは、ブローカーからの次のメッセージを処理するために待つ必要がありません。ブローカーと一度通信し、多くのメッセージを処理することで、パフォーマンスを向上させることができます。ブローカーからのメッセージの取得は(たとえローカルであっても)、ローカルメモリへのアクセスに比べれば高価です。ワーカーはまた、バッチでメッセージを承認することができます。

  2. ゼロに設定されたプリフェッチは、無制限ではなく "特定の制限なし" を意味します。

  3. プリフェッチを 1 に設定することは、それをオフにすることと同等であると文書化されていますが、これは常にそうであるとは限りません ( https://stackoverflow.com/a/33357180/71522 )

  4. プリフェッチにより、メッセージを一括で承認することができます。CELERY_ACKS_LATE=True は、メッセージがワーカーに到達したときに確認することを防ぎます。