通过在它们之间移动一些属性,我已经在我的一个App Engine应用程序中更新了几个使用频繁的NDB模型。因此,某些模型现在包含我的应用程序的先前版本将在不同位置查找的数据(并且这样做失败)。我已经更新了我的处理程序,以确保在我运行伴随我的发布的迁移后不会发生这种情况。
但是,我担心在架构迁移时会发生什么。我已经用几百个实体在本地测试了我的迁移,任务花了大约1秒钟(使用deferred' s)。由于我在生产中有超过1000个实体,我想这个任务实际上需要几秒钟。与此同时,我确信用户会遇到服务问题。
从其他问题(例如this one),我收集到一个好的做法是将用户重定向到一个页面,提醒他们计划的维护停机时间。但是,对我来说这不是一个真正的选择 - 我们需要尽可能保持正常运行时间。
因此,我的问题是:有没有办法让我的应用程序保持在线并仍然执行可能冗长的迁移?我正在考虑使用App Engine" Traffic Splitting"
,这会在新的应用版本迁移时保持用户使用旧的应用版本,但这仍会导致服务问题。答案 0 :(得分:2)
您可以进行2次迁移(添加 + 删除),而不是单次迁移(移动)。
第一次迁移只需添加要移动到模型中新位置的属性。
更新读取属性的代码以首先检查新位置,如果属性不存在,则回退到旧位置。对于2个位置,查询可能需要加倍,并添加逻辑以识别并跳过重复的结果。几乎是新代码和旧代码的组合。
然后,您可以更新编写属性的代码以使用新位置。在此时刻创建的实体不再拥有旧位置。如果你想让它更安全(能够回滚到更旧的代码版本),或者如果你想让你的旧应用程序版本运行一段时间,你可以在新旧位置编写代码。
然后运行一次性作业,将属性内容从旧位置(如果存在)复制到新位置。这可确保所有实体的新位置都存在所有属性。
此时您可以删除访问旧位置的所有代码。
这是不归路。在下一步之前,您需要停止运行旧应用程序代码的任何GAE实例 - 它们不再能够正常运行,并且您无法在没有其他数据库更新作业的情况下回滚代码。
然后运行一次性清理工作,从所有实体的旧位置删除属性 - 最新版本的代码不再访问它们。
完成第二次迁移删除模型中旧位置的属性。
可能需要做很多工作,但无论迁移的持续时间如何,都应该可以实现零停机时间(对于最新的应用版本)。
更新:
中描述了一种可能更好的迁移算法(避免有问题的OR
加倍查询)