我的数据库中有一堆Feed对象,我试图让每个Feed每小时更新一次。我的问题是,我需要确保没有任何重复更新 - 它需要每小时发生一次,但我也不希望Feed等待两个小时进行更新。 (如果它每小时发生+/-几分钟就可以了,但几分钟内发生两次是不好的。)
我正在使用Django和Celery与Amazon SQS作为经纪人。我将Feed更新代码设置为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 recipe和an adaptation on Stack Overflow),但memcached解决方案不可靠,例如重新启动memcached时可能会发生重复,或者当它发生内存不足并清除旧数据时可能会发生重复。更不用说我不想为了简单的锁定而将memcached添加到我的生产配置中。
在一个完美的世界里,我希望能够说:
@modelTask(Feed, run_every=3600)
def updateFeed(feed):
# do something expensive
但到目前为止,我的想象力使我无法实现该装饰器。
答案 0 :(得分:0)
要明确的是,Celery配方本身并没有使用memcached,而是使用Django的缓存中间件。有许多其他缓存方法可以满足您的需求而没有memcached的缺点。有关详细信息,请参阅the Django caching documentation。