2

對於GAE Datastore中的所有數據,我都有一個跟蹤計數器/總記錄數的模型(因爲我們不能使用傳統的SUM查詢)。我想知道在插入/刪除記錄時增加這些全局計數值的最有效方法。這是我目前正在做的事情:Google App Engine計數器

counter = DBCounter.all().fetch(1) 
dbc = DBCounter(totalTopics=counter[0].totalTopics+1) 
dbc.put() 

但是,這對我來說似乎相當sl sl。有沒有更好的方法來做到這一點?

回答

4

如果您需要在計數時保持可擴展性,您應該查看Joe Gregorio關於sharding counters和DocSavage的implementation的文章。

AppEngineFan的優秀博客還提供可擴展的非分片計數器的信息,請參閱this one,它使用任務隊列並指向上一篇使用cron作業的文章。

5

有你的方法的幾個問題:

  • 它可以在數,因爲你不使用事務原子地更新計數器。
  • 效率低下:
    • 如果您需要頻繁更新此計數器,爭用可能會成爲問題。由於您只有一個櫃檯,因此不會很好地擴展。數據存儲實體只能以每秒最多5次的速率寫入。
    • 您每次插入記錄時都要寫入數據存儲區兩次。如果最終使用事務來解決上述問題,那麼每次插入記錄(一次插入記錄和一次更新計數器)時,您都會對數據存儲進行兩次往返。您可能可以使用避免這種額外往返數據存儲的方法。

這裏有一些替代方法(從最不準確的[和最快]以最準確的[和最慢):

  • 如果你只需要實體的數量的粗略計數數據存儲中的特殊類型,那麼你可以使用Stats API。但是,您檢索的計數並不會不斷更新。
  • 如果您需要更多的粒度,但可以偶爾計數不足,那麼您可以使用memcache增強的計數器。在this question中討論了幾個很好的實現。具體來說,請參閱this recipe中的註釋中的代碼。
  • 如果你真的想避免計數不足,那麼你應該考慮一個sharded datastore counter。這將消除上面的爭用問題。
+0

優秀的提示。非常感謝。 – GivP 2010-10-03 15:45:40