安排数据导出

本页介绍了如何安排导出 Firestore 数据。若要按时间表运行导出作业,我们建议使用 Cloud Functions 和 Cloud Scheduler。

准备工作

在安排托管式数据导出作业之前,您必须先完成以下几项任务:

  1. 为 Google Cloud 项目启用结算功能。只有启用了结算功能的 Google Cloud 项目才能使用导出和导入功能。
  2. 导出操作需要一个目标 Cloud Storage 存储分区。在 Firestore 数据库位置附近创建一个 Cloud Storage 存储分区。执行导出操作时,您不能使用启用了“请求者付款”功能的存储分区。

创建 Cloud Functions 函数和 Cloud Scheduler 作业

请按照以下步骤创建一个 Node.js Cloud Functions 函数(用于启动 Firestore 数据导出作业)和一个 Cloud Scheduler 作业(用于调用该函数):

Firebase CLI
  1. 安装 Firebase CLI。在一个新目录中,初始化该 CLI 以用于 Cloud Functions:

    firebase init functions --project PROJECT_ID
    1. 选择 JavaScript 作为语言。
    2. (可选)启用 ESLint。
    3. 输入 y 来安装依赖项。
  2. functions/index.js 文件中的代码替换为以下内容:

    const functions = require('firebase-functions');
    const firestore = require('@google-cloud/firestore');
    const client = new firestore.v1.FirestoreAdminClient();
    
    // Replace BUCKET_NAME
    const bucket = 'gs://BUCKET_NAME';
    
    exports.scheduledFirestoreExport = functions.pubsub
                                                .schedule('every 24 hours')
                                                .onRun((context) => {
    
      const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT;
      const databaseName =
        client.databasePath(projectId, '(default)');
    
      return client.exportDocuments({
        name: databaseName,
        outputUriPrefix: bucket,
        // Leave collectionIds empty to export all collections
        // or set to a list of collection IDs to export,
        // collectionIds: ['users', 'posts']
        collectionIds: []
        })
      .then(responses => {
        const response = responses[0];
        console.log(`Operation Name: ${response['name']}`);
      })
      .catch(err => {
        console.error(err);
        throw new Error('Export operation failed');
      });
    });
    
  3. 在上面的代码中,进行以下修改:
    • BUCKET_NAME 替换为您存储分区的名称。
    • 修改 every 24 hours 以设置导出时间表。使用 AppEngine cron.yaml 语法unix-cron 格式 (* * * * *)。
    • 修改 collectionIds: [] 以仅导出指定的集合组。按原样导出所有集合。

  4. 部署此预定函数:

    firebase deploy --only functions
Cloud Console
创建 Cloud Functions 函数
  1. 打开 Cloud Console 中的 Cloud Functions 页面:

    打开“Cloud Functions”页面

  2. 点击创建函数
  3. 输入函数名称,例如 firestoreExport
  4. 触发器下,选择 Cloud Pub/Sub
  5. 主题下,选择创建新主题。为 Pub/Sub 主题输入一个名称,例如 initiateFirestoreExport。请记下此主题名称,以便在创建 Cloud Scheduler 作业时使用。
  6. 源代码下,选择內嵌编辑器。在 index.js 下输入以下代码:
    const firestore = require('@google-cloud/firestore');
    const client = new firestore.v1.FirestoreAdminClient();
    // Replace BUCKET_NAME
    const bucket = 'gs://BUCKET_NAME'
    
    exports.scheduledFirestoreExport = (event, context) => {
      const databaseName = client.databasePath(
        process.env.GCLOUD_PROJECT,
        '(default)'
      );
    
      return client
        .exportDocuments({
          name: databaseName,
          outputUriPrefix: bucket,
          // Leave collectionIds empty to export all collections
          // or define a list of collection IDs:
          // collectionIds: ['users', 'posts']
          collectionIds: [],
        })
        .then(responses => {
          const response = responses[0];
          console.log(`Operation Name: ${response['name']}`);
          return response;
        })
        .catch(err => {
          console.error(err);
        });
    };
    在上面的代码中,进行以下修改:
    • BUCKET_NAME 替换为您存储分区的名称。
    • 修改 collectionIds: [] 以仅导出指定的集合组。按原样导出所有集合。

  7. package.json 下,添加以下依赖项:
    {
      "dependencies": {
        "@google-cloud/firestore": "^1.3.0"
      }
    }
  8. 要执行的函数下,输入 scheduledFirestoreExport(即 index.js 中函数的名称)。
  9. 点击创建以部署此 Cloud Functions 函数。
创建 Cloud Scheduler 作业

接下来,创建一个 Cloud Scheduler 作业以调用您的 Cloud Functions 函数:

  1. 打开 Cloud Console 中的 Cloud Scheduler 页面:

    打开“Cloud Scheduler”页面

  2. 点击创建作业
  3. 为作业输入名称,例如 scheduledFirestoreExport
  4. 请输入频率,例如 every 24 hours
  5. 选择时区
  6. 目标下选择 Pub/Sub。在主题字段中,输入与 Cloud Functions 函数一起定义的 Pub/Sub 主题的名称,即上例中的 initiateFirestoreExport
  7. 载荷字段中,输入 start export。该作业需要定义载荷,但是上述 Cloud Functions 函数实际上并不使用此值。
  8. 点击创建
至此,您已经部署了 Cloud Functions 函数和 Cloud Scheduler 作业,但是 Cloud Functions 函数仍然需要访问权限才能执行导出操作。

配置访问权限

接下来,请向 Cloud Functions 函数授予开始导出操作以及向 GCS 存储分区写入内容的权限。

此 Cloud Functions 函数使用您项目的默认服务帐号来对其导出操作进行身份验证和授权。当您创建项目时,系统将使用以下名称为您创建一个默认服务帐号:

PROJECT_ID@appspot.gserviceaccount.com

该服务帐号需要具备启动导出操作和向 Cloud Storage 存储分区写入内容的权限。要授予这些权限,请将以下 IAM 角色分配给默认服务帐号:

  • Cloud Datastore Import Export Admin
  • 存储分区中的 OwnerStorage Admin 角色

您可以使用 gcloudgsutil 命令行工具分配这些角色。

如果尚未安装,您可以通过 Google Cloud Console 中的 Cloud Shell 访问这些工具:
启动 Cloud Shell

  1. 分配 Cloud Datastore Import Export Admin 角色。 替换 PROJECT_ID,然后运行以下命令:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:PROJECT_ID@appspot.gserviceaccount.com \
        --role roles/datastore.importExportAdmin
    
  2. 分配针对存储分区的 Storage Admin 角色。替换 PROJECT_IDBUCKET_NAME,然后运行以下命令:

    gsutil iam ch serviceAccount:PROJECT_ID@appspot.gserviceaccount.com:admin \
        gs://BUCKET_NAME
    

如果您停用或删除 App Engine 默认服务帐号,您的 App Engine 应用将无法访问 Firestore 数据库。 如果您停用了 App Engine 服务帐号,则可以重新启用该帐号,请参阅启用服务帐号。如果您在过去 30 天内删除了 App Engine 服务帐号,则可以恢复服务帐号,请参阅取消删除服务帐号

测试您的 Cloud Scheduler 作业和 Cloud Functions 函数

您可以在 Google Cloud Console 的 Cloud Scheduler 页面中测试 Cloud Scheduler 作业。

  1. 打开 Cloud Console 中的 Cloud Scheduler 页面。
    打开“Cloud Scheduler”页面

  2. 在新 Cloud Scheduler 作业所在的行中,点击立即运行

    几秒钟后,Cloud Scheduler 作业应该会将结果列和上次运行时间分别更新为成功和当前时间。您可能需要点击刷新

通过 Cloud Scheduler 页面,您只能确认该作业调用了您的 Cloud Functions 函数。您可以打开 Cloud Functions 函数页面来查看函数日志。

查看 Cloud Functions 函数日志

如需查看 Cloud Functions 函数是否成功启动了导出操作,请打开该函数的日志:

Firebase 控制台

打开 Firebase 控制台中的 Cloud Functions 页面。

打开“函数日志”页面

GCP Console

打开 Cloud Console 中的 Cloud Functions 页面。

打开“日志查看器”页面

查看导出操作进度

您可以使用 gcloud firestore operations list 命令看导出操作的进度,具体请查阅管理导出和导入操作

导出操作完成后,您可以查看 Cloud Storage 存储分区中的输出文件:

打开 Cloud Storage 浏览器