これについてはセロリgithub repoに未解決の問題があります。彼らがそれに取り組んでいるかどうかわからない。
回避策として、特定のPeriodicTaskのインスタンスが1回だけ実行されるように、タスクのロックを追加することができます。以下のような
何か:ロック・タイムアウトを考え出す
if not cache.add('My-unique-lock-name', True, timeout=lock_timeout):
return
は、十分に注意が必要です。異なるセロリがそれらを異なる時間に実行しようとすると、0.9 * task run_every秒を使用しています。 0.9少し余裕を残すだけです(たとえば、セロリが予定より少し遅れている場合は、スケジュールどおりにロックがアクティブになる)。
次に、すべてのマシンでcelerybeatインスタンスを使用できます。各タスクはすべてのcelerybeatインスタンスに対してキューに入れられますが、その中の1つのタスクだけが実行を終了します。
タスクは、このようにrun_everyを尊重します。最悪の場合のシナリオ:タスクは0.9 * run_everyの速度で実行されます。
タスクがキューに登録されていても、スケジュールされた時刻に処理されなかった場合(たとえば、キュープロセッサが利用できないなど)、ロックが間違ったタイミングで実行され、次のタスクが実行されない可能性があります。これを回避するには、タスクが時間的に多かれ少なかれ、何らかの検出メカニズムが必要になります。
これは、本番環境で使用するときは一般的な状況ではありません。
もう1つの解決策は、セリビットスケジューラをサブクラス化し、そのダニ法を無効にすることです。その後、すべてのチックに対して、タスクを処理する前にロックを追加します。これにより、同じ定期タスクを持つセロリだけが同じタスクを複数回キューしないようにします。各ティック(競合状態に勝つ者)のセリビットは1つだけタスクを待ち行列に入れます。 1つのセロリが落ち、次のチックで他の人がレースに勝つ。
もちろん、これは最初の解決策と組み合わせて使用できます。
もちろん、これを行うには、キャッシュバックエンドをすべてのサーバーで複製および共有する必要があります。
これは古い質問ですが、誰にも役立つことを願っています。