从任务队列运行appengine备份

时间:2013-09-13 17:29:31

标签: google-app-engine cron database-backups

在Google App Engine的1.8.4 release中,它声明:

  

此版本中的数据存储管理员修复程序通过确保现在只能由cron或任务队列任务启动计划备份来提高安全性。管理员仍然可以通过管理控制台中的数据存储管理员启动备份。

记录了使用cron运行预定备份的方法,但是我们如何从任务队列任务启动备份?

还有其他方法可以以编程方式运行备份任务吗?

2 个答案:

答案 0 :(得分:7)

您可以使用方法GET和URL“/_ah/datastore_admin/backup.create”创建任务队列任务,并将您的参数指定为URL的参数,并将任务作为目标运行在'ah-builtin-python-bundle上'版本。例如:

url = '/_ah/datastore_admin/backup.create?filesystem=blobstore&name=MyBackup&kind=Kind1&kind=Kind2'
taskqueue.add(
        url=url,
        target='ah-builtin-python-bundle',
        method='GET',
        )

我有cron作业触发我自己的处理程序,然后查找配置并根据该配置创建任务队列备份。这使我可以更改备份设置,而无需更新cron作业,让我有更多的控制权。

您可以在URL中指定的选项与文档针对CRON job backups描述的选项相同,因此您也可以指定namespace和gs-bucket-name。

我相信在Java中你必须在队列定义中创建一个带有目标的队列,并将你的任务添加到该队列。

答案 1 :(得分:2)

我是通过将Bryce的解决方案与googles计划备份文档中的代码相结合来实现的。这样,我仍然使用cron.yaml,但我可以灵活地在每个环境中进行差异(例如,不要在基于数据存储区中的配置的dev / stage分支中运行备份,不要在URL中指定类型还没有脱离开发者。)

我还能够使用以下方法生成& kind = xxx对:

    from google.appengine.ext.ndb import metadata
    backup_types = "".join(["&kind=" + kind for kind in metadata.get_kinds()  if not kind.startswith("_")])

回想起来,步骤非常简单。

设置:

a)Enable your default cloud storage bucket

b)Enable datastore admin

步骤:

  1. 添加一个cron作业以启动备份(cron.yaml):

    cron:
    - description: daily backup
      url: /taskqueue-ds-backup/
      schedule: every 24 hours from 21:00 to 21:59
    
  2. 添加队列以处理任务(queue.yaml):

    - name: ds-backup-queue
      rate: 1/s
      retry_parameters:
        task_retry_limit: 1
    
  3. 将路由添加到任务队列处理程序:

    routes = [...,
              RedirectRoute('/taskqueue-ds-backup/',
                 tasks.BackupDataTaskHandler, 
                 name='ds-backup-queue', strict_slash=True), ...]
    
  4. 添加处理程序以处理排队的项目:

    from google.appengine.api import app_identity
    from google.appengine.api import taskqueue
    from google.appengine.ext.ndb import metadata
    import config
    
    class BackupDataTaskHandler(webapp2.RequestHandler):
        def get(self):
            enable_ds_backup = bool(config.get_config_setting("enable_datastore_backup", default_value="False"))
            if not enable_ds_backup:
                logging.debug("skipping backup. backup is not enabled in config")
                return
    
            backup_types = "".join(["&kind=" + kind for kind in metadata.get_kinds() if not kind.startswith("_")])
    
            file_name_prefix = app_identity.get_application_id().replace(" ", "_") + "_"
            bucket_name = app_identity.get_default_gcs_bucket_name()
    
            backup_url = "/_ah/datastore_admin/backup.create?name={0}&filesystem=gs&gs_bucket_name={1}{2}".format(file_name_prefix, bucket_name, backup_types)
            logging.debug("backup_url: " + backup_url)
    
            # run the backup as a service in production. note this is only possible if you're signed up for the managed backups beta.
            if app_identity.get_application_id() == "production-app-id":
                backup_url += "&run_as_a_service=T"
    
            taskqueue.add(
                    url=backup_url,
                    target='ah-builtin-python-bundle',
                    method='GET',
                    )
            logging.debug("BackupDataTaskHandler completed.")