GAE / P:处理最终的一致性

时间:2013-01-28 03:54:21

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

在may app中,我有以下过程:

  1. 获取很长的人员名单
  2. 为每个人创建实体
  3. 向每个人发送电子邮件(步骤2必须在第3步开始之前完成)
  4. 因为人员名单非常大,所以我不想把它们放在同一个实体组中。

    在执行第3步时,我可以查询这样的人员列表:

    Person.all()
    

    由于最终的一致性,我可能会错过第3步中的某些人。有什么方法可以确保我在第3步中没有错过任何人?

    有比这更好的解决方案吗?:

    while Person.all().count() < N:
        pass
    for p in Person.all()
        # do whatever
    

    编辑:

    我想到了另一种可能的解决方案。我可以创建一个人的链表。我可以存储第一个链接,他可以链接到第二个链接。然而,似乎性能会很差,因为你每个人都会单独获得并且不会有查询的效率。

1 个答案:

答案 0 :(得分:0)

更新:我重读了您的帖子,发现您不想将它们全部放在同一个实体组中。如果不这样做,我不确定如何保证强一致性。您可能希望重新构建数据,以便不必将它们放在同一个实体组中,而是放在几个实体组中。也许取决于一组Person实体的某些方面? (例如,他们所在的邮件列表,正在发送的电子邮件类型等)每个人是否只包含姓名和电子邮件地址,还是涉及其他属性?

Google suggests a a few other alternatives

  

如果您的应用程序可能会遇到较重的写入用法,您可能需要考虑使用其他方法:例如,您可能会将最近的帖子放在内存缓存的内存中,并显示最近的混合内容来自内存缓存和数据存储区的帖子,或您可以将它们缓存在Cookie中将某些状态放入网址或其他完全。目标是找到一个缓存解决方案,在用户发布到您的应用程序的时间段内为当前用户提供数据。请记住,如果您在事务中执行get,put或任何操作,您将始终可以看到最近编写的数据。

所以看起来你可能想调查这些可能性,虽然我不确定它们会如何转化为你的应用所需要的。

原始发布:使用ancestor queries.

来自Google的"Structuring Data for Strong Consistency"

  

要获得高度一致的查询结果,您需要使用祖先查询将结果限制为单个实体组。这是有效的,因为实体组是一致性和事务性的单位。所有数据操作都应用于整个组;在整个实体组是最新的之前,祖先查询不会返回其结果。如果您的应用程序依赖于某些查询的高度一致的结果,则在设计数据模型时可能需要考虑这一点。本页讨论了构建数据以支持强一致性的最佳实践。

因此,当您创建Person实体时,请为其设置父实体。我相信你甚至可以让一个特定的实体成为所有其他实体的“父母”,它应该给你强大的一致性。 (尽管我喜欢用祖先来构建我的数据。)

# Gives you the ancestor key
def ancestor_key(kind, id_or_name):
    return db.Key.from_path(kind, id_or_name)

# Kind is the db model your using (should be 'Person' in this case) and
# id_or_name should be the key id or name for the parent
new_person = Person(your_params, parent=ancestor_key('Kind', id_or_name) 

你甚至可以为那些具有相同父级的所有实体进行查询,这很好。但无论如何,这应该可以帮助您获得更一致的结果。