如何为每个Django模型实例安排一个周期性的芹菜任务?

2024-10-16 20:53:20 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我用Django和Celery和Amazon SQS做经纪人。我已经将feed更新代码设置为一个celry任务,但是我没有找到一种方法来防止重复,同时与运行在多个节点上的Celery保持兼容。在

我当前的解决方案是向提要模型添加一个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添加到我的产品配置中。在

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

^{pr2}$

但到目前为止,我的想象力无法实现这个装饰器。在


Tags: 对象django代码数据库thresholdfeedupdatememcached