2011-12-25 53 views
1

我在我的數據庫中有一堆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 recipean adaptation on Stack Overflow),但memcached解決方案並不可靠,例如在重新啓動memcached或發生內存不足並清除舊數據時可能發生重複。更不用說我不想爲了簡單鎖定而將memcached添加到我的生產配置中。

在一個完美的世界,我希望能夠說:

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

但到目前爲止,我無法想象我對如何實現裝飾。

回答

0

需要說明的是,Celery配方本身並未使用memcached,而是使用Django的緩存中間件。還有其他一些緩存方法可以滿足您的需求,而不會造成memcached的負面影響。有關詳細信息,請參見the Django caching documentation