2011-05-30 97 views
14

我是App Engine的新手,我想确认我对高复制数据存储的理解。App Engine高复制数据存储

该文件说实体组是一个“一致性单元”,并且所有数据最终一致。同样,它也表示“跨实体组的查询可能是陈旧的”。

有人可以提供一些例子,查询可以“陈旧”吗?是不是说我可以在没有任何父母的情况下保存一个实体(即它是自己的组),然后很快查询并找不到它?这是否也意味着如果我希望数据始终保持100%的最新状态,我需要将它们全部保存在同一个实体组中?

对于使用memcache来缓存实体的时间比使数据在所有数据中心中保持一致的平均时间长一段时间,这是常见的解决方法吗?这是什么球场延迟?

感谢

回答

18

难道说我可能会救 一个实体没有任何父(即它的 自己的组),然后查询很 不久后找不到呢?

正确。从技术上讲,这种情况也适用于常规的主 - 从数据存储,因为索引是异步更新的,但实际上,可能发生的时间窗口非常小,您从来不会看到它。

如果通过“查询”您的意思是“做一个按键获取”,但是,这将始终返回在任一实现中强烈一致的结果。

这是否意味着也说如果我想数据 是始终为100%,跟上时代的我需要 保存他们所有的同一实体 组?

您需要在可以回答之前定义“100%最新”的含义。

就是这个共同的解决办法,以 使用内存缓存缓存的 一段时间实体比一般 花费的时间进行数据成为所有数据中心 一致更长?

否。Memcache严格用于改善访问时间;你不应该在缓存驱逐会导致麻烦的任何情况下使用它。

如果您需要保证您看到最新版本,则始终可以获得强一致的获取。但是,如果没有你想要做的具体事例,很难提供建议。

+1

对不起,我没有一个具体的例子。我在学习这个系统,所以我可以开始做我的项目。我只想将数据存储在数据存储中,并在需要时检索最新版本。我只是想弄清楚什么时候不是这种情况,以及我如何保证在查询结果时我会得到最新的结果。通过“查询”我的意思是通过属性查询,就像SQL中的一样,而不是按键。我只想了解祖先团体的意思是“一致性的单位”,什么可以是“不一致的”。 – amatsukawa 2011-05-30 19:43:43

+0

Nick,在此文档的使用说明部分:http://code.google.com/intl/zh-CN/appengine/docs/python/datastore/hr/overview.html说,“您可以将最近发布的内容放入memcache中过期,然后显示来自memcache的最近发布的帖子和从数据存储中检索的帖子。“ – fjsj 2011-09-07 13:31:20

+0

@ user439383(你有没有考虑过设置一个更有用的用户名?)我个人不会再担心这件事,除非你有特定的情况它是关心的。最终一致的语义在大多数情况下都很好,你会知道什么时候需要强大的一致性。 – 2011-09-08 00:45:09

11

强制性博客示例设置; AuthorsPosts

class Author(db.Model): 
    name = db.StringProperty() 

class Post(db.Model): 
    author = db.ReferenceProperty() 
    article = db.TextProperty() 

bob = Author(name='bob') 
bob.put() 

要记住第一件事是在一个单一的实体组(包括单一实体),经常GET/PUT /删除将作为预期:

post1 = Post(article='first article', author=bob) 
post1.put() 

fetched_post = Post.get(post1.key()) 
# fetched_post is latest post1 

你只能通知如果您开始在多个实体组之间进行查询,则会出现不确定性。除非您已指定parent属性,否则您的所有实体都位于不同的实体组中。所以,如果重要的是后直bob创建了一个帖子,说他可以看到有自己的职位的话就要小心了以下内容:

fetched_posts = Post.all().filter('author =', bob).fetch(x) 
# fetched_posts _might_ contain latest post1 

fetched_posts威力包含来自bob最新post1,但它可能不。这是因为所有Posts都不在同一个实体组中。当在HR中这样查询时,你应该认为“可能是我的最新帖子”

由于作者在创建后可以在列表中直接看到他的帖子,因此我们将使用parent属性将它们绑定在一起,并使用ancestor查询来仅从该内容中获取帖子组:

post2 = Post(parent=person, article='second article', author=bob) 
post2.put() 

bobs_posts = Post.all().ancestor(bob.key()).filter('author =', bob).fetch(x) 

现在我们知道post2将在我们bobs_posts结果。

如果我们的查询的目的是为了获取“可能所有最新的帖子+鲍勃最新的帖子”我们需要做另一个查询。

other_posts = Post.all().fetch(x) 

那么结果other_postsbobs_posts合并在一起,以获得所需的结果。

+0

这实际上是一个很好的解释。只有我不明白的是你的例子中的“人”是什么?一个类或实例? – Houman 2014-01-30 12:07:00

5

刚刚将我的应用程序从主/从设备迁移到高复制数据存储区后,我不得不说,实际上,对于大多数应用程序而言,最终一致性不是问题。

考虑一个典型的留言板示例,在这里您可以在put()的新留言中发布实体,然后立即查询留言板中的所有帖子。使用高复制数据存储,直到几秒钟后(Google I/O,Google工程师表示滞后时间为2-5秒),您才会在查询结果中看到新帖子。

现在,在实践中,您的留言板应用程序可能正在做一个新的留言板帖子条目的AJAX帖子。提交新帖子后不需要重新提交所有帖子。一旦AJAX请求成功,webapp可以简单地将新条目插入UI。在用户离开网页并返回时,甚至点击浏览器刷新按钮时,几秒钟就会过去,并且很有可能新查询将返回到查看所有留言板帖子的查询。

最后,请注意,最终一致性性能仅适用于查询。如果您实体put()立即呼叫db.get()将其取回,则结果将非常一致,即您将获得实体的最新快照。

相关问题