App Engine分片计数器和高复制数据存储

时间:2012-04-20 08:42:01

标签: python google-app-engine google-cloud-datastore eventual-consistency

我正在使用App Engine和最终一致的高复制数据存储。我也在使用分片计数器。

当我查询所有分片并总结它们时,我可以假设计数是非常一致的吗?也就是说,下面的代码会返回我的分片计数的准确总和吗?

sum = 0
for counter in Counter.all():
    sum += counter.count

4 个答案:

答案 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%。