Programa exportaciones de bases de datos de Memorystore para Redis con Cloud Scheduler

Last reviewed 2023-03-18 UTC

En este instructivo, se muestra cómo usar Cloud Scheduler y Cloud Functions para exportar de manera automática una base de datos de Memorystore para Redis a Cloud Storage. Tener exportaciones de bases de datos en Cloud Storage te permite crear un plan sólido y diverso de recuperación ante desastres. Por ejemplo, puedes exportar a una región diferente y, luego, importar a otras instancias de Memorystore para Redis.

Arquitectura

En este instructivo, se incluyen los siguientes componentes de Google Cloud:

Un trabajo de Cloud Scheduler publica un mensaje en un tema de Pub/Sub con información sobre el ID de instancia de Memorystore, el ID del proyecto, la región donde se encuentra y la ubicación de Cloud Storage en la que se almacenará la copia de seguridad. Este evento activa una Cloud Function que obtiene esta carga útil y comienza una exportación de base de datos en Memorystore para Redis a través de su API. La base de datos genera la exportación y la guarda en Cloud Storage. En el siguiente diagrama, se muestra este flujo de trabajo.

Flujo de trabajo de Cloud Scheduler a Pub/Sub, que activa una Cloud Function que inicia la exportación.

Objetivos

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Antes de comenzar

  1. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  2. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  3. En la consola de Google Cloud, activa Cloud Shell.

    Activar Cloud Shell

  4. Habilita las API de Memorystore for Redis, Cloud Functions, Cloud Scheduler, and Cloud Build.

    Habilita las API

A lo largo de este instructivo, ejecutarás todos los comandos desde Cloud Shell.

Configure su entorno

Para comenzar, primero configura tu entorno y, luego, crea funciones personalizadas que tengan los permisos necesarios para este instructivo.

  1. En Cloud Shell, configura las siguientes variables de entorno:

    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 FUNCTION_NAME="${DEMO}-gcf"
    export PUBSUB_TOPIC="${DEMO}-topic"
    export SCHEDULER_JOB="${DEMO}-job"
    export MEM_EXPORT_ROLE="memExporter"
    export STORAGE_ROLE="simpleStorageRole"
    export REGION="us-central1"
    
  2. Crea dos funciones personalizadas que solo tengan los permisos necesarios para este instructivo:

    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_EXPORT_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"
    

    Estas funciones reducen el permiso de acceso de las cuentas de servicio de Cloud Functions y Memorystore, según el principio de privilegio mínimo.

Crea un bucket de Cloud Storage y una instancia de Memorystore.

En esta sección, primero debes crear un bucket de Cloud Storage y una instancia de Memorystore para Redis. Luego, propagas los datos de muestra con Memorystore.

Crea un bucket de Cloud Storage

Usa la herramienta de línea de comandos de gsutil para crear un bucket de Cloud Storage.

  • Crea un bucket de Cloud Storage en el que desees guardar las exportaciones de datos:

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

Crea una instancia de Memorystore y otorga permisos a su cuenta de servicio

A continuación, debes crear una instancia de Memorystore y otorgarle a su cuenta de servicio los permisos para exportar datos a Cloud Storage.

  1. Crea una instancia de Memorystore para Redis 4 como sigue:

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

    Esta operación tardará unos minutos en completarse.

  2. Verifica que la instancia de Memorystore sea READY:

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

    El resultado es similar al siguiente:

    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. Otorga a tu cuenta de servicio de Memorystore los permisos para exportar datos a Cloud Storage con la función personalizada Simple Storage que creaste antes:

    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}
    

Crea la tarea de exportación de datos programada

En esta sección, debes crear una cuenta de servicio personalizada y vincularla a la función de Redis personalizada que creas. Luego, crea un tema de Pub/Sub que se usa para activar la ejecución de una función de Cloud Functions. También creas un trabajo de Cloud Scheduler para ejecutar de forma periódica la función de exportación de datos.

Crea una cuenta de servicio para la función de Cloud Functions

El primer paso es crear una cuenta de servicio y vincularla a los roles.

  1. Crea una cuenta de servicio de IAM para que la Cloud Function la use y guárdala en la siguiente variable:

    gcloud iam service-accounts create ${FUNCTION_NAME} \
        --display-name="Service Account for GCF and Memorystore"
    
    export GCF_SA=$(gcloud iam service-accounts list --filter="${FUNCTION_NAME}" --format="value(email)")
    
  2. Otorga a la cuenta de servicio acceso al rol personalizado Memorystore Exporter que le permite solicitar exportaciones de Memorystore:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${GCF_SA}" \
        --role="projects/${PROJECT_ID}/roles/${MEM_EXPORT_ROLE}"
    
  3. Otorga a la cuenta de servicio acceso al rol personalizado Simple Storage

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

Crea un tema de Pub/Sub

El siguiente paso es crear un tema de Pub/Sub que se use para activar la Cloud Function que interactúa con la base de datos de Memorystore.

  • Crea el tema de Pub/Sub:

    gcloud pubsub topics create ${PUBSUB_TOPIC}
    

Crea una función de Cloud Functions

A continuación, crea la Cloud Function.

  1. Crea una carpeta para el código de la Cloud Function:

    mkdir scheduler_gcf_code && cd scheduler_gcf_code
    
  2. Para crear un archivo main.py, pega lo siguiente en 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
        instance_name=pubsub_message['name'].split("/")[-1]
        uri = f"{pubsub_message['gs']}/backup-{instance_name}-{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. Para crear un archivo requirements.txt, pega lo siguiente en Cloud Shell:

    cat <<EOF > requirements.txt
    
    google-api-python-client
    Oauth2client
    EOF
    
  4. Implementa el código.

    gcloud functions deploy ${FUNCTION_NAME} \
        --trigger-topic=${PUBSUB_TOPIC} \
        --runtime=python37 \
        --entry-point=main \
        --service-account=${FUNCTION_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \
        --ingress-settings=internal-and-gclb
    

Crea un trabajo de Cloud Scheduler

Por último, crea un trabajo de Cloud Scheduler para ejecutar de forma periódica la función de exportación de datos.

  1. Guarda el nombre completo de Memorystore en una variable:

    export MEM_NAME=$(gcloud redis instances describe ${MEM_INSTANCE} --region ${REGION} --format "value(name)")
    
  2. Crea un trabajo de Cloud Scheduler para ejecutar de forma periódica la función de exportación de datos:

    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' --location=${REGION}
    

    Este trabajo está programado para ejecutarse a las 11:00 p.m. (hora del Pacífico) todos los días.

    El cuerpo del mensaje contiene el nombre de la instancia de Memorystore que se exportará y el bucket de Cloud Storage de destino.

Prueba tu solución

El último paso es probar la solución. Para comenzar, ejecuta el trabajo de Cloud Scheduler.

  1. Ejecuta el trabajo de Cloud Scheduler de forma manual para activar la exportación de Memorystore de tu base de datos.

    gcloud scheduler jobs run ${SCHEDULER_JOB} --location=${REGION}
    
  2. Enumera las operaciones realizadas en la instancia de Memorystore y verifica que haya una operación del tipo EXPORT:

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

    En el siguiente ejemplo de resultado, se muestra un trabajo de exportación con un estado DONE de True para indicar que se completó. Si el estado DONE muestra False, esto indica que el trabajo aún se está procesando. Espera un minuto y vuelve a ejecutar el comando anterior.

    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. Verifica el bucket de Cloud Storage para ver si se creó el archivo de exportación:

    gsutil ls -l gs://${BUCKET_NAME}/*.rdb
    

    Verás un archivo llamado backup-INSTANCE_NAME-TIMESTAMP.rdb.

Limpia

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo. La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?