App Engine 分片计数器和高复制数据存储
Posted
技术标签:
【中文标题】App Engine 分片计数器和高复制数据存储【英文标题】:App Engine Shard Counters and High Replication Datastore 【发布时间】:2012-05-01 20:14:50 【问题描述】:我将 App Engine 与最终一致的 High Replication Data Store 结合使用。我也在使用分片计数器。
当我查询所有分片并将它们相加时,我可以假设计数是强一致的吗?也就是说,下面的代码会返回我的分片计数的准确总和吗?
sum = 0
for counter in Counter.all():
sum += counter.count
【问题讨论】:
不完全是一个答案,但你知道你可以只做my_sum=sum(counter.count for counter in Counter.all())
,当然调用变量sum
是在问问题。
好点,忘记了。
【参考方案1】:
没有。即使按键获取,您也不能依赖高度一致的计数(尽管它会比其他方式更新)。批量获取操作不是事务性的,因此可以在您获取其中一个分片时对其进行更新。
然而,在这里要求强一致性是没有意义的。首先,在像 App Engine 这样的分布式系统中,同时性在最好的时候是一个模糊的概念——同步需要协调,这会产生瓶颈。其次,即使您可以获得计数器值的交易总和,但在您获取它的那一刻它已经过时了,因为无论如何在您读取它们之后计数器可以立即更新。
【讨论】:
【参考方案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)
在事务中执行递增以确保一致性。
【讨论】:
【参考方案3】:您可以增加分片计数器总计当前状态的概率,但您不能(据我所知)将该概率提高到 100%。
【讨论】:
【参考方案4】:查询最终在 HRD 中是一致的,因此您无法确定通过查询获得的实体是否已更新。如果查询依赖于正在更新的实体属性,那么查询甚至可能找不到实体。
【讨论】:
以上是关于App Engine 分片计数器和高复制数据存储的主要内容,如果未能解决你的问题,请参考以下文章
当一个人创建一个新模型时,应该在哪里放置代码以在 Google App Engine/Django 上自动增加一个分片计数器?
Google App Engine 数据存储区中每秒写入 5 次以上的事务计数器
在“编译”时不知道属性名称的情况下,在 Python 中复制 Google App Engine 数据存储区中的实体