4

我很困惑。

我今天注意到,我认为应该存在于我的生产 appengine 应用程序中的一些数据没有显示出来。我通过远程控制台连接到应用程序并手动运行查询。果然,看起来我希望看到的 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状态确实列出了今天的服务中断),但我有一个感觉这将自行解决。有的话会再更新。

最后更新

正如我所怀疑的,当我今天早上醒来时,我的应用程序(和手动查询)现在可以看到一致、正确的数据视图。仍然希望得到关于为什么会发生这种情况的答案,但在我得到答案之前,我会将其归结为 Google 内部的 bigtable 怪异。

我向 appengine 提出了这个问题,看看我是否能从知情人士那里得到答案。

4

1 回答 1

0

对于 HRD 应用程序,这是按预期工作的。App Engine High Replication Datastore (HRD) 将您的数据同步存储在多个数据中心中。但是,从提交写入到它在所有数据中心中可见的延迟意味着跨多个实体组的查询(非祖先查询)只能保证最终一致的结果。[1]

在您的特定情况下,您的应用程序和管理控制台数据存储查看器的结果之间的差异仅仅是因为它们很可能是从具有不同一致性的不同数据存储服务器读取的。

如果您需要一致的数据视图,我建议您仔细查看文章“Structuring Data for Strong Consistency”

[1] https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency

于 2013-10-20T21:54:32.923 回答