1

データベースに多数のフィード オブジェクトがあり、各フィードを 1 時間ごとに更新しようとしています。ここでの問題は、重複した更新がないことを確認する必要があることです。1 時間に 1 回しか発生しないようにする必要がありますが、フィードが更新のために 2 時間待機することも望ましくありません。(1 時間 +/- 数分ごとに発生する場合は問題ありませんが、数分に 2 回発生するのは問題です。)

私は Django と Celery を Amazon SQS と共にブローカーとして使用しています。Celery タスクとしてフィード更新コードをセットアップしましたが、複数のノードで実行されている Celery との互換性を維持しながら、重複を防ぐ方法を見つけることができません。

私の現在の解決策は、Feed モデルに属性を追加し、last_update_scheduled5 分ごとに次のタスクを実行することです (疑似コード)。

threshold = datetime.now() - timedelta(seconds=3600)
for f in Feed.objects.filter(Q(last_update_scheduled__lt = threshold) |
                             Q(last_update_scheduled = None)):
    updateFeed.delay(f)
    f.last_update_scheduled = now
    f.save()

これは、多くの同期の問題の影響を受けやすくなっています。たとえば、タスク キューがバックアップされると、このタスクが同時に 2 回実行され、更新が重複する可能性があります。これに対するいくつかの解決策を見てきました ( Celery のレシピStack Overflow の適応など) が、memcached の解決策は信頼できません。言うまでもなく、単純なロックのためだけに memcached を本番構成に追加する必要はありません。

完璧な世界では、次のように言えるようになりたいです。

@modelTask(Feed, run_every=3600)
def updateFeed(feed):
    # do something expensive

しかし、これまでのところ、そのデコレータを実装する方法について私の想像力は失敗しています。

4

1 に答える 1

0

明確にするために、Celery レシピは memcached 自体を使用しているのではなく、Django のキャッシング ミドルウェアを使用しています。memcached のマイナス面がなくてもニーズに合ったキャッシング方法は他にもたくさんあります。詳細については、Django キャッシングのドキュメントを参照してください。

于 2011-12-26T08:42:55.623 に答える