2011-06-23 10 views
4

セロリビットを使用して1分に1回実行するタスクがあります。それはうまく動作します。しかし、場合によっては、タスクの実行に2分の時間がかかり、実行に数分かかることがあります。これは物事を混乱させる競合状態に繋がります。セルラービートで一度に1つのタスクしか実行されないようにする

私の仕事は正しく動作するように修正できますが、セロリーにはこれを確実にするための組み込み方法があるかどうかを知りたかったのです。私の大雑把なGoogle検索とRTFMでは結果が得られませんでした。

+1

私はそれをpidファイルのようなものを使って解決しました。完璧な解決策ではありませんが、うまく動作しています – Rustem

答えて

0

あなたはyoureの実行を行う機能を保持しているオブジェクトにclassfieldを追加してみてください、あなたはcronのスケジュールや時間を使用している場合は、「他の男は仕事やされていない」コントロールとして

+1

私は自分のコードを変更することによって多くの方法が考えられます。セレリービートがこのようなものを提供しているかどうかを知りたい –

1

をそのフィールドを使用することができます定期的なタスクを実行するための間隔はまだ問題があります。 dbやキャッシュ、あるいはファイルシステムを使っていつでもロック機構を使うことができますし、前のものから次のタスクをスケジュールすることもできます。 この質問はおそらくあなたを助けることができます。 django celery: how to set task to run at specific interval programmatically

+0

私はこれらを試してみます。ありがとう! –

+0

ちょうど参照のために、私は、時間間隔が最後の_started_実行後ではなく_finished_実行後にタスクを一定の時間実行することを確かめています。実際、Celerybeatは実行のために送信された後でもタスクを追跡していないと思う。 – nitwit

+0

@nitwitあなたは完全に正しいです。私の答えでは、「最後の執行の後に」と言います。 :-) 「これは起こってはいけない」と言って間違っているのも事実です。それに応じて答えを編集します。ありがとう –

2

あなたは可能性がadd a lock、memcachedのか、単にあなたのデシベルのようなものを使用しました。

+0

これは良い解決策です。ちょうど好奇心が強い、なぜ彼らは例でそれらのラムダを使用していますか?なぜ 'add'と' delete'を直接呼び出さないのでしょうか?セマンティクスを伝えるために、私は仮定しますか? – mgalgs

0

ロックは、ビートとクーロンのどちらでも良い方法です。

ただし、ビートジョブは、ビート実行時ではなく、ワーカーの開始時刻で実行されることに注意してください。

これは私がロックでも競合状態に陥る原因となっていました。ワーカーはオフになっており、ビートは10のジョブをキューに投げ込みます。セロリが4つのプロセスで起動すると、4人すべてがタスクを取得し、私の場合は1または2がロックを取得して同時に設定します。

解決策1つは、作業者の開始時ではなく、その時点でcronが実行されるため、ロック付きのcronを使用することです。

解決策2は、競合状態を処理する少し高度なロック機構を使用することです。赤ちゃんの場合はsetnx、またはそれより新しいものはredlockです。 このブログの投稿は本当にうれしく、redis-pyのロック機構を使用するデコレータパターン:http://loose-bits.com/2010/10/distributed-task-locking-in-celery.htmlが含まれています。

関連する問題