1

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

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

我当前的解决方案是向last_update_scheduledFeed 模型添加一个属性,并每 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 的配方对 Stack Overflow 的改编),但 memcached 解决方案并不可靠,例如,在重新启动 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 回答