我正在使用App Engine和最终一致的高复制数据存储。我也在使用分片计数器。
当我查询所有分片并总结它们时,我可以假设计数是非常一致的吗?也就是说,下面的代码会返回我的分片计数的准确总和吗?
sum = 0
for counter in Counter.all():
sum += counter.count
答案 0 :(得分:4)
没有。即使按键获取,也不能依赖强烈一致的计数(尽管它会比其他情况更新)。批量获取操作不是事务性的,因此在获取它们时可以更新其中一个分片。
然而,在这里要求强烈的一致性是没有意义的。首先,在像App Engine这样的分布式系统中,同时性是最好的模糊概念 - 同步需要协调,这会产生瓶颈。其次,即使您可以获得计数器值的事务总和,它在您获取它的那一刻也会过时,因为计数器可以在您阅读之后立即更新。答案 1 :(得分:2)
如果要创建强一致的分片计数器,则应使用密钥,而不是查询。
#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)
在事务中执行递增以确保一致性。
答案 2 :(得分:0)
查询最终在HRD中是一致的,因此您无法确定通过查询获得的实体是否已更新。如果查询依赖于正在更新的实体属性,那么查询可能甚至找不到该实体。
答案 3 :(得分:0)
您可以增加分片计数器总计当前状态的概率,但您不能(据我所知)将该概率提高到100%。