在另一个增量复制之前迁移到高复制数据存储区后,是否可以安全地触摸数据?

时间:2012-03-13 20:50:50

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

为了迁移我们的应用程序(2年,数据量相当),我计划使用recommended tool

我们的一些实体存储了序列化词典,并引用了键,因此我们需要转换它们以更改键的应用程序名称部分。我的问题是,更改已迁移的数据会不会影响迁移工具对增量复制期间需要迁移的内容的理解?例如,安全:

  • 启动迁移工具
  • 运行我们的自定义工具以迁移存储的密钥(在新应用中)
  • 验证我们的应用有效
  • 运行增量副本
  • 再次运行我们的工具

2 个答案:

答案 0 :(得分:1)

事实证明,在迁移过程中,目标应用程序处于只读模式,因此在迁移完成之前运行目标hrd应用程序上的任何修复工具都不是一种选择。

相反,我的方法现在是使用补丁db.get来动态重写密钥,然后在迁移后修复目标应用程序中的引用。到目前为止,我已经验证了我的新hrd应用程序可以正常使用猴子补丁。一旦新版本生效,我就必须要修复引用,但事实如此。

from google.appengine.ext import db
import os

APP_ID = os.getenv('APPLICATION_ID')

def replace_key(key_str, app_id=None):
    app_id = app_id or APP_ID
    oldkey = db.Key(key_str) if not isinstance(key_str, db.Key) else key_str
    if oldkey.app() != app_id:
        fixedkey = str(db.Key.from_path(oldkey.kind(), oldkey.id_or_name(), _app=app_id))
        logging.info("rewriting %s to %s", str(oldkey), fixedkey)
        return fixedkey
    else:
        return key_str

old_get = db.get

def monkeyed_get(keys, **kwargs):
    single = False
    if isinstance(keys, (basestring, db.Model, db.Key)):
        single = True
        keys = [keys]

    results = old_get(map(lambda k: replace_key(str(k)), keys), **kwargs)
    return results[0] if single else results

db.get = monkeyed_get

答案 1 :(得分:1)

我们将目标应用程序设置为只读的唯一原因是为了防止像您的任务队列或cron作业一样在部分复制的数据上运行,这可能会在目标应用程序中产生错误的数据。

可以手动将目标数据存储区置于读写模式或编写自定义MR,该MR使用覆盖只读设置的数据存储区选项来修复序列化实体,作为过程的一部分。

迁移工具仅查找主/从应用程序中的更改,然后盲目地将它们复制到HRD应用程序。如果您在HRD应用程序中进行更改,如果对主/从应用程序中的同一实体进行了更改,它们将被覆盖。

话虽这么说,我实际上赞成你的方法,它支持并按需修复密钥。您还可以编写MapReduce来修复此方法尚未修复的任何引用。