我在我的數據庫中有一堆Feed對象,我試圖讓每個Feed每小時更新一次。我的問題在於,我需要確保沒有任何重複的更新 - 每小時只需發生一次,但我也不希望Feed等待兩個小時進行更新。 (沒關係,如果它每小時發生+/-幾分鐘,但在幾分鐘內兩次都不好)。如何爲每個Django模型實例安排週期性的Celery任務?
我使用Django和Celery作爲Amazon SQS作爲代理。我將訂閱源更新代碼設置爲Celery任務,但我無法找到防止重複的方法,同時與在多個節點上運行的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 recipe和an adaptation on Stack Overflow),但memcached解決方案並不可靠,例如在重新啓動memcached或發生內存不足並清除舊數據時可能發生重複。更不用說我不想爲了簡單鎖定而將memcached添加到我的生產配置中。
在一個完美的世界,我希望能夠說:
@modelTask(Feed, run_every=3600)
def updateFeed(feed):
# do something expensive
但到目前爲止,我無法想象我對如何實現裝飾。