我正在使用App Engine和最終一致的高度複製數據存儲。我也使用分片計數器。App Engine碎片計數器和高度複製數據存儲
當我查詢所有碎片並將其總結時,我可以假設這些計數是非常一致的嗎?也就是說,下面的代碼會返回我的碎片計數的精確總和嗎?
sum = 0
for counter in Counter.all():
sum += counter.count
我正在使用App Engine和最終一致的高度複製數據存儲。我也使用分片計數器。App Engine碎片計數器和高度複製數據存儲
當我查詢所有碎片並將其總結時,我可以假設這些計數是非常一致的嗎?也就是說,下面的代碼會返回我的碎片計數的精確總和嗎?
sum = 0
for counter in Counter.all():
sum += counter.count
如果你想創建高度一致的分片計數器,你應該使用鍵而不是查詢。
#for getting
total = 0
shard_keys = []
for i in range(20): #20 shards
key_name = shard + str(i)
shard_keys.append(db.Key.from_path('Counter', key_name))
counters = db.get(shard_keys)
for counter in counters:
if counter:
total += counter.count
#for incrementing a shard
import random
key_name = 'shard' + str(int(random.random()*20)) #choose a random shard
counter = Counter.get_by_key_name(key_name) #try to retrieve from datastore
if not counter:
counter = Counter(key_name=key_name) #shard doesn't exist, create one
counter.count += 1
db.put(counter)
在事務中執行遞增以確保一致性。
有道理,謝謝。 – 2012-04-20 17:24:14
查詢在HRD中最終一致,因此您無法確定通過查詢獲取的實體是否已更新。如果查詢取決於正在更新的實體屬性,那麼查詢甚至可能找不到該實體。
您可以增加分片計數器總計當前狀態的概率,但是您不能(據我所知)將該概率設置爲100%。
不可以。即使通過密鑰獲取,也不能依賴強有力的一致計數(儘管它會比其他方式更新)。批量獲取操作不是事務性的,因此在獲取它們時可以更新其中一個碎片。
然而,要求這裏的一致性很有意義。首先,在像App Engine這樣的分佈式系統中,同時性在最好的時候是模糊的概念 - 同步需要協調,這就產生了瓶頸。其次,即使您可以獲得計數器值的交易總和,它在您提取計數器的那一刻也會過時,因爲計數器無論如何都可以在您讀取之後立即更新。
不完全是一個答案,但你知道你可以在counter.all()中執行'my_sum = sum(counter.count for counter)',當然調用一個變量'sum'就是問題。 – hochl 2012-04-20 09:17:24
好點,忘了那個。 – 2012-04-20 17:23:28