2012-02-15 9 views
15

セロリ/ rabbitmq展開の単一障害点であるセロビットを回避するための推奨されるソリューションを探しています。私はこれまでにウェブを検索することで意味をなさないものは見つけられませんでした。セロリビットが単一の障害点になるのを回避する

私の場合、1日1回のタイムスケジューラは、半日以上実行できる一連のジョブを開始します。 celerybeatインスタンスは1つしか存在できないため、実行中のサーバーやサーバーに何か問題が発生した場合、重要なジョブは実行されません。

私は信頼できる(クラスタ化された、または同様の)スケジューラを必要とする唯一の人にはなれないので、すでにこのための解決策が存在することを望んでいます。私がする必要がなければ、データベースバックアップされたスケジューラに頼るのは嫌です。

答えて

5

これについてはセロリ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つのセロリが落ち、次のチックで他の人がレースに勝つ。

もちろん、これは最初の解決策と組み合わせて使用​​できます。

もちろん、これを行うには、キャッシュバックエンドをすべてのサーバーで複製および共有する必要があります。

これは古い質問ですが、誰にも役立つことを願っています。

関連する問題