構成オプションCELERYD_PREFETCH_MULTIPLIER
( ドキュメント )。デフォルトは4ですが、(私は信じています)プリフェッチをオフにするか、可能な限り低くしたいです。今は1に設定しています。これは探しているものに十分近いですが、まだ理解できないことがいくつかあります。
なぜこれを先読みするのが良い考えですか?メッセージキューとワーカーの間に大きな遅延がない限り、その理由は実際にはわかりません(私の場合、現在同じホストで実行されており、最悪の場合、同じデータの異なるホストで実行される可能性があります)センター)。ドキュメントには欠点のみが記載されていますが、その利点については説明されていません。
多くの人々はこれを0に設定しているようで、そのようにプリフェッチをオフにできると期待しています(私の意見では合理的な仮定)。ただし、0は無制限のプリフェッチを意味します。なぜ誰もが無制限のプリフェッチを望んでいるのに、そもそもタスクキューを導入した並行性/非同期性を完全に排除しないのでしょうか?
プリフェッチをオフにできないのはなぜですか?ほとんどの場合、パフォーマンスをオフにするのは得策ではないかもしれませんが、これが不可能になる技術的な理由はありますか?それとも実装されていないだけですか?
時々、このオプションはCELERY_ACKS_LATE
。例えば。 Roger Huが書いています "[…]しばしば[ユーザー]が本当に望んでいるのは、ワーカーに子プロセスと同数のタスクのみを予約させることです。しかし、これは遅延確認を有効にしないと不可能です[…]"これら2つのオプションがどのように接続されているのか、なぜ一方が他方なしでは不可能なのか理解できません。接続についての別の言及は here にあります。誰かが2つのオプションが接続されている理由を説明できますか?
プリフェッチはパフォーマンスを改善できます。ワーカーは、ブローカーからの次のメッセージが処理されるのを待つ必要はありません。ブローカーと一度通信して大量のメッセージを処理すると、パフォーマンスが向上します。ブローカからメッセージを取得することは、ローカルメモリアクセスであっても、ローカルメモリアクセスに比べて高価です。ワーカーはバッチでメッセージを確認することもできます
ゼロに設定されたプリフェッチは、無制限ではなく「特定の制限なし」を意味します
プリフェッチを1に設定することは、それをオフにすることと同等であると文書化されていますが、常にそうであるとは限りません( https://stackoverflow.com/a/33357180/71522 を参照)
プリフェッチにより、メッセージをバッチで確認することができます。 CELERY_ACKS_LATE = Trueは、メッセージがワーカーに届くときにメッセージを確認できないようにします
古い質問ですが、誰かを助けるために私の答えを追加します。いくつかの初期テストからの私の理解は、David Woleverの答えと同じでした。セロリ3.1.19でこれをさらにテストしたところ、-Ofair
は機能します。ワーカーノードレベルでプリフェッチを無効にすることを意図したものではありません。それは起こり続けます。 -Ofair
を使用すると、プールワーカーレベルで異なる効果があります。要約すると、プリフェッチを完全に無効にするには、次を実行します。
CELERYD_PREFETCH_MULTIPLIER = 1
を設定CELERY_ACKS_LATE = True
を設定します-Ofair
を使用しますさらに詳細を追加します。
ワーカーノードはデフォルトで常にプリフェッチされることがわかりました。 CELERYD_PREFETCH_MULTIPLIER
を使用して、プリフェッチするタスクの数のみを制御できます。 1に設定されている場合、ノード内のプールワーカーの数(同時実行)と同数のタスクのみをプリフェッチします。したがって、並行性= nの場合、ノードによってプリフェッチされる最大タスクはnになります。
-Ofair
オプションがないと、プールワーカープロセスの1つが長時間実行されるタスクを実行している場合、ノード内の他のワーカーも、ノードによって既にプリフェッチされたタスクの処理を停止します。 -Ofair
を使用することにより、変更されました。ノードのワーカーの1つが長時間実行タスクを実行していても、他のワーカーは処理を停止せず、ノードによってプリフェッチされたタスクの処理を続行します。したがって、プリフェッチには2つのレベルがあります。ワーカーノードレベルで1つ。もう1つは、個々のワーカーレベルです。 -Ofair
を使用すると、ワーカーレベルで無効になったようです。
ACKS_LATE
はどのように関連していますか? 。先読みされたメッセージは、rabbitmqの「認識されていないメッセージ」の下に表示されることに気付きました。したがって、ACKS_LATE = True
は、タスクが成功した場合にのみタスクが承認されることを意味します。そうでない場合、それは労働者によって受け取られたときに起こると思います。プリフェッチの場合、タスクは最初にワーカーによって受信されます(ログから確認されます)が、後で実行されますTrue
に設定することが絶対に必要かどうかはわかりません。とにかく、他の理由でタスクをそのように設定しました(遅刻)。
警告:redisブローカー+ Celery 3.1.15でのテストの時点で、プリフェッチを無効にする_CELERYD_PREFETCH_MULTIPLIER = 1
_に関して読んだアドバイスはすべて間違いなく間違っています。
これを実証するには:
CELERYD_PREFETCH_MULTIPLIER = 1
_を設定time.sleep(5)
)Redisでタスクキューの長さの監視を開始します:_watch redis-cli -c llen default
_
_celery worker -c 1
_を開始
5
_から_3
_にすぐに下がることに注意してください。_CELERYD_PREFETCH_MULTIPLIER = 1
_はプリフェッチを防止しません。プリフェッチをキューごとに1タスクに制限します。
_-Ofair
_、 ドキュメントの記載にもかかわらず 、またはプリフェッチを防止しません。
ソースコードを変更する以外に、プリフェッチを完全に無効にする方法は見つかりませんでした。
私のstackcredは十分に高くないので、David Woleverの答えにコメントすることはできません。だから、私は自分の経験をCelery 3.1.18とMongodbブローカーと共有したいので、答えを答えとして組み立てました。次の方法でプリフェッチを停止できました。
CELERYD_PREFETCH_MULTIPLIER = 1
セロリの設定へCELERY_ACKS_LATE = True
セロリの設定へ--concurrency=1 -Ofair
CELERY_ACKS_LATEをデフォルトのままにしておくと、ワーカーは引き続きプリフェッチします。 OPのように、プリフェッチとレイトACKの間のリンクを完全には把握していません。 Davidが「CELERY_ACKS_LATE = Trueはメッセージがワーカーに届いたときにメッセージの確認を防ぐ」と言っていることは理解していますが、レイトACKがプリフェッチと互換性がない理由を理解できません。理論的には、プリフェッチは、セロリでそのようにコーディングされていない場合でも、まだ遅刻を許可しますか?