Programar exportações de dados

Veja nesta página como agendar exportações dos seus dados do Cloud Firestore. Para executar as exportações em um cronograma, recomendamos implantar um serviço do App Engine que chame o recurso de exportação gerenciada do Cloud Firestore. Após a implantação, você poderá agendar as chamadas para esse serviço usando o serviço Cron do App Engine.

Antes de começar

Antes de planejar exportações de dados com o recurso de exportação gerenciada, conclua as seguintes tarefas:

  1. Ative o faturamento do seu projeto do Google Cloud Platform. Somente os projetos do GCP com faturamento ativado podem usar o recurso de exportação e importação.
  2. Crie um intervalo do Cloud Storage para seu projeto em um local próximo ao do banco de dados do Cloud Firestore. Não é possível usar um intervalo de pagamentos do solicitante para as operações de exportação e importação.
  3. Instale o SDK do Google Cloud para conceder permissões de acesso e implantar o aplicativo.

Configurar as permissões de acesso

O aplicativo usa a conta de serviço padrão do App Engine para autenticar e autorizar as operações de exportação. Quando você cria um projeto, a conta de serviço padrão é gerada para você com o seguinte formato:

YOUR_PROJECT_ID@appspot.gserviceaccount.com

A conta de serviço precisa de permissão para iniciar uma operação de exportação e gravar no seu intervalo do Cloud Storage. Para conceder essas permissões, atribua as seguintes funções de IAM para a conta de serviço padrão:

  • Cloud Datastore Import Export Admin
  • Papel Owner ou Storage Admin no intervalo.

É possível usar as ferramentas de linha de comando gcloud e gsutil do SDK do Google Cloud para atribuir esses papéis:

  1. Transfira o papel Administrador de exportação e importação do Cloud Datastore:

    gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
        --member serviceAccount:YOUR_PROJECT_ID@appspot.gserviceaccount.com \
        --role roles/datastore.importExportAdmin
    
  2. Transfira o papel Administrador do Storage ao seu intervalo:

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

Arquivos de aplicativos

Em uma nova pasta, crie os seguintes arquivos de aplicativo usando o código abaixo:

app.yaml
Configura o ambiente de execução do App Engine. O app usa o ambiente de execução padrão do ambiente do Node.js.
app.js
O código principal do app. Este aplicativo configura um serviço da Web em https://YOUR_PROJECT_ID.appspot.com que inicia as operações de exportação.
package.json
Inclui informações sobre o aplicativo e suas dependências.
cron.yaml
Configura um cron job que chama o serviço da Web.

app.yaml

runtime: nodejs8

O código acima presume que este aplicativo é o aplicativo padrão. Se ele não for, adicione a seguinte linha:

target: cloud-firestore-admin

app.js

const axios = require('axios');
const dateformat = require('dateformat');
const express = require('express');
const { google } = require('googleapis');

const app = express();

// Trigger a backup
app.get('/cloud-firestore-export', async (req, res) => {
  const auth = await google.auth.getClient({
    scopes: ['https://www.googleapis.com/auth/datastore']
  });

  const accessTokenResponse = await auth.getAccessToken();
  const accessToken = accessTokenResponse.token;

  const headers = {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ' + accessToken
  };

  const outputUriPrefix = req.param('outputUriPrefix');
  if (!(outputUriPrefix && outputUriPrefix.indexOf('gs://') == 0)) {
    res.status(500).send(`Malformed outputUriPrefix: ${outputUriPrefix}`);
  }

  // Construct a backup path folder based on the timestamp
  const timestamp = dateformat(Date.now(), 'yyyy-mm-dd-HH-MM-ss');
  let path = outputUriPrefix;
  if (path.endsWith('/')) {
    path += timestamp;
  } else {
    path += '/' + timestamp;
  }

  const body = {
    outputUriPrefix: path
  };

  // If specified, mark specific collections for backup
  const collectionParam = req.param('collections');
  if (collectionParam) {
    body.collectionIds = collectionParam.split(',');
  }

  const projectId = process.env.GOOGLE_CLOUD_PROJECT;
  const url = `https://firestore.googleapis.com/v1beta1/projects/${projectId}/databases/(default):exportDocuments`;

  try {
    const response = await axios.post(url, body, { headers: headers });
    res
      .status(200)
      .send(response.data)
      .end();
  } catch (e) {
    if (e.response) {
      console.warn(e.response.data);
    }

    res
      .status(500)
      .send('Could not start backup: ' + e)
      .end();
  }
});

// Index page, just to make it easy to see if the app is working.
app.get('/', (req, res) => {
  res
    .status(200)
    .send('[scheduled-backups]: Hello, world!')
    .end();
});

// Start the server
const PORT = process.env.PORT || 6060;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});

package.json

{
  "name": "solution-scheduled-backups",
  "version": "1.0.0",
  "description": "Scheduled Cloud Firestore backups via AppEngine cron",
  "main": "app.js",
  "engines": {
    "node": "8.x.x"
  },
  "scripts": {
    "deploy": "gcloud app deploy --quiet app.yaml cron.yaml",
    "start": "node app.js"
  },
  "author": "Google, Inc.",
  "license": "Apache-2.0",
  "dependencies": {
    "axios": "^0.18.0",
    "dateformat": "^3.0.3",
    "express": "^4.16.4",
    "googleapis": "^34.0.0"
  },
  "devDependencies": {
    "prettier": "^1.14.3"
  }
}

cron.yaml

cron:
- description: "Daily Cloud Firestore Export"
  url: /cloud-firestore-export?outputUriPrefix=gs://BUCKET_NAME[/PATH]&collections=test1,test2
  target: cloud-firestore-admin
  schedule: every 24 hours

Modifique a linha de url para configurar a operação de exportação. O aplicativo configura um serviço em https://YOUR_PROJECT_ID.appspot.com/cloud-firestore-export que aceita os seguintes parâmetros de URL:

outputUriPrefix
A localização do seu intervalo do Cloud Storage no formato gs://BUCKET_NAME.
collections
Uma lista separada por vírgulas de códigos de coleções a serem exportados. Se não for especificada, a operação exportará todas as coleções.

Por exemplo, para exportar todas as coleções com o código de coleção Songs ou Albums, você usaria o seguinte comando:

url: /cloud-firestore-export?outputUriPrefix=gs://BUCKET_NAME&collections=Songs,Albums

O exemplo cron.yaml executa uma exportação a cada 24 horas. Para diferentes opções, consulte o formato de programação.

Implantar o aplicativo e o cron job

Usando o gcloud, implante o aplicativo e o cron job:

gcloud app deploy app.yaml cron.yaml

Testar seu cron job

Teste o cron job implantado ao iniciar ele na página Cron Jobs do Console do Google Cloud Platform.

  1. Abra a página Cron Jobs no Console do GCP.
    Abrir a página "Cron jobs"

  2. Para o cron job com uma descrição Exportação diária do Cloud Firestore, clique em Executar agora.

  3. Depois que job for concluído, consulte a mensagem de status em Status. Clique em Ver para visualizar o registro do job. A mensagem de status e o log do job fornecerão informações sobre o sucesso ou a falha do trabalho.

Ver suas exportações

Depois que uma operação de exportação for concluída, será possível visualizar as exportações no seu intervalo do Cloud Storage:

Abra o navegador do Cloud Storage no Console do GCP.
Abra o navegador do Cloud Storage

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.