我很沮丧。
我今天注意到我认为应该出现在我的生产appengine app中的一些数据没有显示出来。我通过远程控制台连接到应用程序并手动运行查询。果然看起来我只有我想要看到的101行中的15行。
然后我访问了appengine.google.com的管理控制台,并使用以下查询启动了数据存储区查看器:
SELECT * FROM Assignment where game = KEY('Game', '201212-foo') and player = KEY('Player', 'player-mb')
我看到的结果是20个结果的第一页。我翻阅了这些结果,并且能够看到所有101个实体。万岁!我的数据仍在那里。但为什么我不能通过db api访问它? (注意:我已经尝试通过memcache查看器清除memcache,即使这个特殊查询不是手动memcached)
从远程控制台:
> from google.appengine.ext.db import GqlQuery
> GqlQuery("SELECT * FROM Assignment WHERE game = KEY('Game', '201212-foo') and player = KEY('Player', 'player-mb')").count()
15
远程控制台同意应用程序本身,它似乎只能看到预期的101行中的15行。
是什么给出了?
更新:
我怀疑这可能是一个索引问题。如果我为其中一个缺失行发出get_by_key_name,它随后会显示在db api查询中。
> GqlQuery("SELECT * FROM Assignment WHERE game = KEY('Game', '201212-foo') and player = KEY('Player', 'player-mb')").count()
15
> entities.Assignment.get_by_key_name('201212-assignment-135.9')
<entities.Assignment object at 0xa11eb6c>
> GqlQuery("SELECT * FROM Assignment WHERE game = KEY('Game', '201212-foo') and player = KEY('Player', 'player-mb')").count()
16
我应该(或者我可以)重建我的索引来解决这个问题吗?
更新#2 :
我试图为这个查询构建一个完美的索引,并且刚刚验证了即使查询确实使用了刚构建的索引(通过query.index_list()),结果仍然仅限于一小部分通过数据存储区查看器提供的项目。令人愤怒的是,它实际上是与之前索引不同的子集(20项与15项)。因此,现在添加额外的过滤条件会导致返回额外的5行。太蠢了。
所有索引都声称“正在服务”,因此索引不应该有任何原因。
更新#3 :
有时,使用我的新索引,我会得到正确答案:
> GqlQuery("SELECT * FROM Assignment WHERE game = KEY('Game', '201212-foo') and player = KEY('Player', 'player-mb') and user = 'zee'").count()
101
但是,如果我发出10次这样的查询,那么大约一半的时间会出现'糟糕'的结果:
> GqlQuery("SELECT * FROM Assignment WHERE game = KEY('Game', '201212-foo') and player = KEY('Player', 'player-mb') and user = 'zee'").count()
16
所以也许这是一个糟糕/落后的大表复制品的问题,我有一半的时间,或者其他完全不透明的问题我们无法得到答案(appengine status确实列出服务中断今天),但我觉得这将是自己修复的。如果确实会再次更新。
最终更新:
我怀疑,当我今天早上醒来时,我的应用程序(和手动查询)现在可以看到一致,正确的数据视图。仍然会喜欢为什么会发生这种情况的答案,但在我明白这一点之前,我将把它归结为内部Google巨大的怪异。
我提交了this针对appengine的问题,看看我是否能从知道的人那里得到答案。
答案 0 :(得分:0)
对于HRD应用程序,这是按预期工作的。 App Engine高复制数据存储(HRD)将您的数据同步存储在多个数据中心中。但是,从提交写入到在所有数据中心中变为可见的延迟意味着跨多个实体组(非祖先查询)的查询只能保证eventually consistent结果。 [1]
在您的特定情况下,应用程序的结果与管理控制台数据存储查看器之间的差异仅仅是因为它们很可能是从具有不同一致性的不同数据存储区服务器读取的。
如果您需要一致的数据视图,我建议您仔细查看文章"Structuring Data for Strong Consistency"
[1] https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency