Como programar exportações de banco de dados do Memorystore para Redis usando o Cloud Scheduler

Neste tutorial, mostramos como usar o Cloud Scheduler e o Cloud Functions para exportar automaticamente um banco de dados do Memorystore para Redis para o Cloud Storage. Ter exportações de banco de dados no Cloud Storage permite criar um plano de recuperação de desastres robusto e diversificado. Por exemplo, é possível exportar para uma região diferente e importar para outras instâncias do Memorystore para Redis.

Arquitetura

Este tutorial inclui os seguintes componentes do Google Cloud:

Um job do Cloud Scheduler publica uma mensagem em um tópico do Pub/Sub com informações sobre o código da instância do Memorystore, o código do projeto, a região em que ele está localizado e o local do Cloud Storage em que o armazenamento backup. Esse evento aciona uma Função do Cloud que recebe esse payload e inicia uma exportação de banco de dados no Memorystore para Redis por meio da API. O banco de dados gera a exportação e a salva no Cloud Storage. O diagrama a seguir mostra esse fluxo de trabalho.

Fluxo de trabalho do Cloud Scheduler para o Pub/Sub, que aciona uma Função do Cloud que inicia a exportação.

Objetivos

Custos

Neste tutorial, usamos os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem ser qualificados para uma avaliação gratuita.

Ao concluir este tutorial, exclua os recursos criados para evitar o faturamento contínuo. Para mais informações, consulte Como fazer a limpeza.

Antes de começar

  1. No Console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o projeto.

  3. No Console do Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

  4. Ative as APIs Memorystore para Redis, Cloud Functions, Cloud Scheduler e App Engine.

    Ative as APIs

Ao longo deste tutorial, você executará todos os comandos do Cloud Shell.

Como configurar o ambiente

Para começar, primeiro configure seu ambiente e, em seguida, crie papéis personalizados com as permissões necessárias para este tutorial.

  1. No Cloud Shell, configure estas variáveis de ambiente:

    export PROJECT_ID=`gcloud config get-value project`
    export DEMO="mem-exporter"
    export BUCKET_NAME=${USER}-mem-$(date +%s)
    export MEM_INSTANCE="${DEMO}-instance"
    export GCF_NAME="${DEMO}-gcf"
    export PUBSUB_TOPIC="${DEMO}-topic"
    export SCHEDULER_JOB="${DEMO}-job"
    export MEM_ROLE="memExporter"
    export STORAGE_ROLE="simpleStorageRole"
    export REGION="us-central1"
    
  2. Crie dois papéis personalizados que tenham apenas as permissões necessárias para este tutorial:

    gcloud iam roles create ${STORAGE_ROLE} --project=${PROJECT_ID} \
        --title="Simple Storage Role" \
        --description="Grant permissions to view and create objects in Cloud Storage" \
        --permissions="storage.objects.create,storage.buckets.get"
    
    gcloud iam roles create ${MEM_ROLE} --project=${PROJECT_ID} \
        --title="Memorystore Exporter Role" \
        --description="Grant permissions to export data from a Memorystore instance to a Cloud Storage bucket" \
        --permissions="redis.instances.export"
    

    Esses papéis reduzem o escopo do acesso das contas de serviço do Cloud Functions e do Memorystore, seguindo o princípio do menor privilégio.

Como criar um bucket do Cloud Storage e uma instância do Memorystore

Nesta seção, você criará primeiro um intervalo do Cloud Storage e uma instância do Memorystore para Redis. Em seguida, preencha o Memorystore com dados de amostra.

Criar um bucket do Cloud Storage

Use a ferramenta de linha de comando gsutil para criar um bucket do Cloud Storage.

  • Crie um bucket do Cloud Storage em que você quer salvar as exportações de dados:

    gsutil mb -l ${REGION} gs://${BUCKET_NAME}
    

Criar uma instância do Memorystore e conceder permissões à conta de serviço

Em seguida, crie uma instância do Memorystore e conceda à conta de serviço as permissões para exportar dados para o Cloud Storage.

  1. Crie uma instância do Memorystore para Redis 4:

    gcloud redis instances create ${MEM_INSTANCE} --size=1 --region=${REGION}
    

    Essa operação leva alguns minutos para ser concluída.

  2. Verifique se a instância do Memorystore é READY:

    gcloud redis instances list --region=${REGION}
    

    A saída será assim:

    INSTANCE_NAME   VERSION    REGION       TIER   SIZE_GB  HOST          PORT  NETWORK  RESERVED_IP      STATUS  CREATE_TIME
    redis-instance  REDIS_4_0  us-central1  BASIC  1        10.61.20.131  6379  default  10.61.20.128/29  READY   2020-04-23T18:38:54
    
  3. Conceda à sua conta de serviço do Memorystore as permissões para exportar dados para o Cloud Storage com o papel de armazenamento simples:

    export MEM_SA=$(gcloud redis instances describe ${MEM_INSTANCE} --region ${REGION} \
        --project ${PROJECT_ID} \
        --format "value(persistenceIamIdentity)")
    
    gsutil iam ch ${MEM_SA}:projects/${PROJECT_ID}/roles/${STORAGE_ROLE} gs://${BUCKET_NAME}
    

Como criar um tópico do Pub/Sub, uma função do Cloud e um job do Cloud Scheduler

Nesta seção, você cria uma conta de serviço personalizada e a vincula ao papel do Redis personalizado criado. Em seguida, você criará um tópico do Pub/Sub que será usado para ativar a execução de uma função do Cloud. Você também criará um job do Cloud Scheduler para executar periodicamente a função de exportação de dados.

Criar uma conta de serviço para o Cloud Function

A primeira etapa é criar uma conta de serviço personalizada e vinculá-la ao papel personalizado do Redis que você cria.

  1. Crie uma conta de serviço do IAM para a Função do Cloud usar e salvá-la na variável:

    gcloud iam service-accounts create ${GCF_NAME} \
        --display-name="Service Account for GCF and Memorystore"
    
    export GCF_SA=$(gcloud iam service-accounts list --filter="${GCF_NAME}" --format="value(email)")
    
  2. Conceda à conta de serviço do Cloud Function acesso ao papel personalizado do Redis:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${GCF_SA}" \
        --role="projects/${PROJECT_ID}/roles/${MEM_ROLE}"
    
  3. Conceda à conta de serviço do Cloud Function acesso ao papel de armazenamento personalizado:

    gsutil iam ch \
        serviceAccount:${GCF_SA}:projects/${PROJECT_ID}/roles/${STORAGE_ROLE} \
        gs://${BUCKET_NAME}
    

Criar um tópico do Pub/Sub

A próxima etapa é criar um tópico do Pub/Sub usado para acionar a Função do Cloud que interage com o banco de dados do Memorystore.

  • Crie o tópico do Pub/Sub:

    gcloud pubsub topics create ${PUBSUB_TOPIC}
    

Criar um Cloud Function

Em seguida, crie a função do Cloud.

  1. Crie uma pasta para o código do Cloud Function:

    mkdir scheduler_gcf_code && cd scheduler_gcf_code
    
  2. Crie um arquivo main.py colando o seguinte no Cloud Shell:

    cat <<EOF  > main.py
    
    import base64
    import logging
    import json
    
    from datetime import datetime
    from httplib2 import Http
    
    from googleapiclient import discovery
    from googleapiclient.errors import HttpError
    from oauth2client.client import GoogleCredentials
    
    def main(event, context):
        pubsub_message = json.loads(base64.b64decode(event['data']).decode('utf-8'))
        credentials = GoogleCredentials.get_application_default()
    
        service = discovery.build('redis', 'v1beta1', http=credentials.authorize(Http()), cache_discovery=False)
    
        datestamp = datetime.now().strftime("%Y%m%d%H%M") # format timestamp: YearMonthDayHourMinute
        uri = f"{pubsub_message['gs']}/backup-{datestamp}.rdb"
    
        request_body = {
            "outputConfig": {
                "gcsDestination" : {
                    "uri": uri
                }
            }
        }
    
        try:
            request = service.projects().locations().instances().export(
                name=pubsub_message['name'],
                body=request_body
            )
    
            response = request.execute()
        except HttpError as err:
            logging.error(f"Could NOT run backup. Reason: {err}")
        else:
            logging.info(f"Backup task status: {response}")
    EOF
    
  3. Crie um arquivo requirements.txt colando o seguinte no Cloud Shell:

    cat <<EOF > requirements.txt
    
    google-api-python-client
    Oauth2client
    EOF
    
  4. Implante o código. Quando for perguntado se você quer permitir invocações não autenticadas da nova função, responda no.

    gcloud functions deploy ${GCF_NAME} \
        --trigger-topic=${PUBSUB_TOPIC} \
        --runtime=python37 \
        --entry-point=main \
        --service-account=${GCF_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
    

Criar um job do Cloud Scheduler

Por fim, crie um job do Cloud Scheduler para executar periodicamente a função de exportação de dados.

  1. Crie uma instância do App Engine para o job do Cloud Scheduler:

    gcloud app create --region=${REGION::-1}
    
  2. Salve o nome completo do Memorystore em uma variável:

    export MEM_NAME=$(gcloud redis instances describe ${MEM_INSTANCE} --region ${REGION} --format "value(name)")
    
  3. Crie um job do Cloud Scheduler para executar periodicamente a função de exportação de dados:

    gcloud scheduler jobs create pubsub ${SCHEDULER_JOB} \
        --schedule='0 23 * * *' --topic=${PUBSUB_TOPIC} \
        --message-body='{"name":'\"${MEM_NAME}\"',"gs":'\"gs://${BUCKET_NAME}\"'}' \
        --time-zone='America/Los_Angeles'
    

    Esse job está programado para ser executado às 23h todos os dias.

Como testar sua solução

A etapa final é testar a solução. Para começar, execute o job do Cloud Scheduler.

  1. Execute o job do Cloud Scheduler manualmente para acionar uma exportação do Memorystore do banco de dados.

    gcloud scheduler jobs run ${SCHEDULER_JOB}
    
  2. Liste as operações realizadas na instância do Memorystore e verifique se há uma operação do tipo EXPORT:

    gcloud redis operations list --region=${REGION} --filter="${MEM_INSTANCE}"
    

    A saída mostra um job de exportação concluído, por exemplo:

    OPERATION_NAME                                           REGION       TYPE    TARGET                 DONE  CREATE_TIME          DURATION
    operation-1592329364987-5a837122a600c-b22c2703-5077c6b7  us-central1  export  mem-exporter-instance  True  2020-06-16T17:42:45  16S
    
  3. Verifique o intervalo do Cloud Storage para ver se o arquivo de exportação foi criado:

    gsutil ls gs://${BUCKET_NAME} | grep rdb
    

    Você verá um arquivo chamado backup-mem-timestamp.rdb após a operação STATUS da etapa anterior retornar DONE.

Como fazer a limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, siga estas etapas. A maneira mais fácil de evitar o faturamento é excluir o projeto criado para o tutorial.

  1. No Console do Cloud, acesse a página Gerenciar recursos:

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

A seguir