【问题标题】:In Google App Engine, how can I work with eventual consistency in handling form submissions?在 Google App Engine 中,如何在处理表单提交时实现最终一致性?
【发布时间】:2016-01-15 19:45:48
【问题描述】:

我注意到,在最终保持一致的情况下,我习惯的常见表单处理工作流程(提交 -> 创建/更新记录 -> 重定向 -> 重新加载)不起作用。重定向后,新记录(可能)将无法显示。我应该如何处理表单以便在重新加载时显示更新?

我可以尝试使用强一致性,但正如App Engine documentation 所述,更新仅限于one update per second。

那么,如何处理提供即时用户反馈并最终保持一致的表单?

【问题讨论】:

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


    【解决方案1】:

    尝试重新构建您的代码,以便通过键(始终为您提供最新数据)而不是进行查询来获取。我意识到这并不总是可能的,但我会给你一个最近的例子,说明一些对我有用的东西。

    我有一个用户仪表板,用户可以在其中创建和删除“项目”。我的实体看起来像这样:

    class User(ndb.Model)
        ...
    
    class Item(ndb.Model)
        user = ndb.KeyProperty(User, required=True)
    

    过去,在响应用户仪表板的 GET 请求时,我会执行这样的查询。

    items = Item.query(user=user.key)
    

    这是一种糟糕的体验,因为用户会删除一个项目,并且在 POST/redirect/GET 之后,由于最终的一致性,刚刚删除的项目会再次出现在仪表板中。

    为了解决这个问题,我将我的用户实体更改为具有这样的项目列表:

    class User(ndb.Model)
        items = ndb.KeyProperty(repeated=True)
        ...
    

    现在,当我显示仪表板时,我会这样做:

    items = ndb.get_multi(user.items)
    

    由于我现在是通过密钥获取的,因此数据始终是最新的。

    这对我有用,因为用户不会拥有那么多项目。但是,如果用户可以拥有数千个项目,那么由于实体大小的限制,这种方法就行不通了。

    【讨论】:

    • 感谢您的回答。它并没有完全回答我的问题,它更侧重于可能超过实体大小限制的案例。不过,您的示例帮助我理解了强一致性可能比我最初理解的更广泛地应用。
    【解决方案2】:

    只要您正确设计实体组,您可能仍然可以使用强一致性。仔细阅读链接的文档,限制实际上是每秒更新一次每个实体组。

    这是因为 Google 的底层无主一致性协议(“Paxos”)仅在实体组(被定义为整个密钥组,在一个根密钥下并包括该根密钥,其中最终父在所有非根密钥中,根密钥是该根密钥 - 请参阅Transactions and entity groups 了解更多信息)。

    参考手册:

    如上所述,实体组是一组通过祖先连接到公共根元素的实体。将数据组织成实体组可以限制可以执行的事务:

    ... [交易详情] ...

    • 在单个实体组中,写入吞吐量限制约为每秒一个事务。存在此限制是因为 Datastore 在广泛的地理区域内对每个实体组执行无主同步复制,以提供高可靠性和容错能力。

    因此,如果您将 Datastore 密钥构建为使用登录用户的 ID 或电子邮件地址作为父密钥,则可以通过将该密钥指定为祖先。

    还值得注意的是,从技术上讲,实体不必存在于该父键中 - 您只需要一个键来启动实体组的根,这样您就可以应用一致性保证。

    如果您可以采用这种方式进行架构,您既可以保证一致性,又可以以每用户每秒一次的速度应用写入,或者您的密钥范围。

    有关详细信息,请参阅"Structuring for Strong Consistency"。

    【讨论】:

    • 感谢您阐明每秒一个事务在单个实体组内的限制。这很重要,并且确实使强一致性更广泛地适用。我仍然对无法构建模型以实现强一致性的情况感兴趣。我将对我的问题进行澄清,并尝试提供一个特定的用例。不过,我很感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-08-19
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多