【问题标题】:How to schedule a periodic Celery task per Django model instance?如何为每个 Django 模型实例安排定期 Celery 任务?
【发布时间】:2011-12-25 16:56:34
【问题描述】:

我的数据库中有一堆 Feed 对象,我试图让每个 Feed 每小时更新一次。我的问题是我需要确保没有任何重复的更新——它需要每小时不超过一次,但我也不希望提要等待两个小时才能更新。 (如果它每小时 +/- 几分钟发生一次也没关系,但几分钟内发生两次是不好的。)

我将 Django 和 Celery 与 Amazon SQS 一起用作代理。我将提要更新代码设置为 Celery 任务,但我未能找到一种方法来防止重复,同时保持与在多个节点上运行的 Celery 兼容。

我目前的解决方案是在 Feed 模型中添加一个last_update_scheduled 属性,并每 5 分钟运行一次以下任务(伪代码):

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()

这容易受到许多同步问题的影响。例如,如果我的任务队列得到备份,该任务可能会同时运行两次,从而导致重复更新。我已经看到了一些解决方案(如Celery's recipean adaptation on Stack Overflow),但memcached 解决方案并不可靠,例如重新启动 memcached 或内存不足并清除旧数据时,可能会发生重复。更不用说我不想为了一个简单的锁而不得不将 memcached 添加到我的生产配置中。

在一个完美的世界里,我想说:

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

但到目前为止,我无法想象如何实现该装饰器。

【问题讨论】:

    标签: python django celery django-celery


    【解决方案1】:

    需要明确的是,Celery 配方本身并不是使用 memcached,而是使用 Django 的缓存中间件。有许多其他缓存方法可以满足您的需求,而没有 memcached 的缺点。详情请见the Django caching documentation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-05
      • 2019-02-16
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 2011-05-22
      相关资源
      最近更新 更多