Migra de DynamoDB a Cloud Spanner

En este instructivo, se describe cómo migrar de Amazon DynamoDB a Cloud Spanner. Por lo general, lo usan propietarios de app que desean trasladarse de un sistema NoSQL a Cloud Spanner, que es un sistema de base de datos SQL muy escalable, 100% racional y tolerante a errores que es compatible con las transacciones. Si usas de forma coherente la tabla de Amazon DynamoDB, en cuanto a tipos y diseños, la asignación a Cloud Spanner es sencilla. Si tus tablas de Amazon DynamoDB contienen tipos y valores de datos arbitrarios, tal vez sería más fácil trasladarse a otros servicios NoSQL, como Cloud Datastore o Firebase.

En este instructivo, se supone que conoces los esquemas de base de datos, los tipos de datos, los aspectos principales de NoSQL y los sistemas de base de datos relacional. El instructivo se basa en la ejecución de tareas predefinidas para realizar una migración de ejemplo. Después del instructivo, puedes modificar el código y los pasos proporcionados para que coincidan con tu entorno.

En el siguiente diagrama arquitectónico, se describen los componentes usados en el instructivo para migrar datos:

Diagrama de la arquitectura de los componentes de migración

Objetivos

  • Migrar datos de Amazon DynamoDB a Cloud Spanner.
  • Crear una base de datos de Cloud Spanner y migrar la tabla.
  • Asignar un esquema NoSQL a un esquema relacional.
  • Crear y exportar un conjunto de datos de muestra que use Amazon DynamoDB.
  • Transferir datos entre Amazon S3 y Cloud Storage.
  • Usar Cloud Dataflow para cargar datos en Cloud Spanner.

Costos

En este instructivo se usan los siguientes componentes facturables de Google Cloud Platform:

  • GKE
  • Cloud Pub/Sub
  • Cloud Storage
  • Cloud Dataflow

Los cargos de Cloud Spanner se calculan según la cantidad de horas por nodo y la cantidad de datos almacenados durante el ciclo de facturación mensual. Durante el instructivo, usarás una configuración mínima de estos recursos que se limpian al final. Para situaciones reales, estima tu capacidad de procesamiento y requisitos de almacenamiento. A continuación, usa la documentación de las instancias de Cloud Spanner para establecer la cantidad de nodos que necesitas.

Además de los recursos de GCP, en este instructivo se usan los siguientes recursos de Amazon Web Services (AWS):

  • Amazon EMR
  • AWS Lambda
  • Amazon S3
  • Amazon DynamoDB

Solo se necesitan estos servicios durante el proceso de migración. Al final del instructivo, sigue las instrucciones para limpiar todos los recursos a fin de evitar cargos innecesarios. Usa la calculadora de precios de AWS para calcular estos costos.

Usa la calculadora de precios a fin de generar una estimación de los costos según el uso previsto. Los usuarios nuevos de GCP pueden optar a una prueba gratuita.

Antes de comenzar

  1. Accede a tu Cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  2. Selecciona o crea un proyecto de GCP.

    Ir a la página Administrar recursos

  3. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

  4. Habilita las Cloud Spanner, Cloud Pub/Sub, Compute Engine y Cloud Dataflow API necesarias.

    Habilita las API

Cuando finalices este instructivo, puedes borrar los recursos que hayas creado para evitar que se continúe con la facturación. Consulta la sección Limpieza para obtener más detalles.

Prepara tu entorno

En este instructivo, ejecutarás comandos en Cloud Shell. En Cloud Shell, se te brinda acceso a la línea de comandos de GCP, incluso el SDK de Cloud y otras herramientas que necesitas para el desarrollo de GCP. La inicialización de Cloud Shell puede tardar varios minutos.

  1. Activa Cloud Shell.

    ACTIVAR Cloud Shell

  2. Establece la zona predeterminada de Compute Engine. Por ejemplo, us-central1-b.

    gcloud config set compute/zone us-central1-b
    
  3. Clona el repositorio de GitHub que contiene el código de muestra.

    git clone https://github.com/GoogleCloudPlatform/dynamodb-spanner-migration.git
    
  4. Ve al directorio clonado.

    cd dynamodb-spanner-migration
    
  5. Crea un entorno virtual de Python.

    virtualenv --python python2 env
    
  6. Activa el entorno virtual.

    source env/bin/activate
    
  7. Instala los módulos requeridos de Python.

    pip install -r requirements.txt
    

Configura el acceso a AWS

En este instructivo, crearás y borrarás tablas de Amazon DynamoDB, depósitos de Amazon S3 y otros recursos. Para acceder a estos recursos, primero debes crear los permisos necesarios de administración de identidades y accesos (IAM) de AWS. Puedes usar una cuenta de AWS de prueba o una zona de pruebas para evitar que se afecten los recursos de producción en la misma cuenta.

Crea una función IAM de AWS para AWS Lambda

En esta sección, crearás una función IAM de AWS que AWS Lambda usa en un paso posterior del instructivo.

  1. En la consola de AWS, ve a la sección de IAM, haz clic en Funciones y, a continuación, selecciona Crear función.
  2. En Elegir el servicio que usará esta función, haz clic en Lambda y, luego, selecciona Siguiente: Permisos.
  3. En el cuadro Tipo de política, ingresa AWSLambdaDynamoDBExecutionRole.
  4. Selecciona la casilla de verificación AWSLambdaDynamoDBExecutionRole y, luego, haz clic en Siguiente: Revisar.
  5. En el cuadro Nombre de la función, ingresa dynamodb-spanner-lambda-role y, luego, haz clic en Crear función.

Crea un usuario IAM de AWS

Sigue estos pasos para crear un usuario IAM de AWS con acceso programático a los recursos de AWS que se usarán en todo el instructivo.

  1. Mientras sigues en la sección de IAM de la consola de AWS, haz clic en Usuarios y, a continuación, selecciona Agregar usuario.
  2. En el cuadro Nombre de usuario, ingresa dynamodb-spanner-migration.
  3. En Tipos de acceso, haz clic en Acceso programático.

  4. Haz clic en Siguiente: Permisos.

  5. Haz clic en Adjuntar las políticas existentes de forma directa y selecciona las dos políticas siguientes:

    • AmazonDynamoDBFullAccesswithDataPipeline
    • AmazonS3FullAccess
  6. Haz clic en Siguiente: Revisar y, a continuación, haz clic en Crear usuario.

  7. Haz clic en Mostrar para ver las credenciales. El ID de clave de acceso y la clave de acceso secreto se muestran para el usuario recién creado. Deja esta ventana abierta por ahora, ya que necesitarás las credenciales en la siguiente sección. Almacena estas credenciales de forma segura, ya que con ellas, puedes realizar cambios en tu cuenta y afectar a tu entorno. Al final de este instructivo, podrás borrar el usuario de IAM.

Configura la interfaz de línea de comandos de AWS

  1. En Cloud Shell, configura la interfaz de línea de comandos de AWS (CLI).

    aws configure
    

    Aparece este resultado:

    $ aws configure
    AWS Access Key ID [None]: PASTE_YOUR_ACCESS_KEY_ID
    AWS Secret Access Key [None]: PASTE_YOUR_SECRET_ACCESS_KEY
    Default region name [None]: us-west-2
    Default output format [None]:
    user@project:~/dynamodb-spanner$
    
    • Ingresa el ACCESS KEY ID y SECRET ACCESS KEY de la cuenta de IAM de AWS que creaste.
    • En el campo Nombre de región predeterminado, ingresa us-west-2. Deja los otros campos con sus valores predeterminados.
  2. Cierra la ventana de la consola de IAM de AWS.

Cómo comprender el modelo de datos

En la siguiente sección, se describen las similitudes y diferencias entre los tipos de datos, índices y claves para Amazon DynamoDB y Cloud Spanner.

Tipos de datos

Cloud Spanner usa los tipos de datos SQL estándar. En la siguiente tabla, se describe cómo los tipos de datos Amazon DynamoDB asignan tipos de datos a Cloud Spanner.

Amazon DynamoDB Cloud Spanner
Número Según la precisión o el uso previsto, se puede asignar a INT64, FLOAT64, MARCA DE TIEMPO o FECHA.
String String
Booleano BOOL
Nulo Sin tipo explícito. Las columnas pueden contener valores nulos.
Binario Bytes
Conjuntos Arreglo
Mapa y lista Realiza la estructura si esta es coherente y se puede describir mediante la sintaxis de la tabla DDL.

Clave primaria

Una clave primaria de Amazon DynamoDB establece la unicidad y puede ser una clave hash o una combinación de una clave hash más una clave de rango. En este instructivo, se comienza con el modelado de la migración de una tabla Amazon DynamoDB cuya clave primaria es una clave hash. Esta clave hash se convierte en la clave primaria de la tabla de Cloud Spanner. Más adelante, en la sección sobre tablas intercaladas, crearás una situación en la que una tabla de Amazon DynamoDB usa una clave primaria compuesta por una clave hash y una clave de rango.

Índices secundarios

Tanto Amazon DynamoDB como Cloud Spanner admiten la creación de un índice en un atributo que no es una clave primaria. Toma nota de los índices secundarios en tu tabla de Amazon DynamoDB para que puedas crearlos en tu tabla de Cloud Spanner, que se explica en una sección posterior de este instructivo.

Tabla de muestra

Para facilitar este instructivo, migra la siguiente tabla de muestra de Amazon DynamoDB a Cloud Spanner:

Amazon DynamoDB Cloud Spanner
Nombre de la tabla Migration Migration
Clave primaria "Username" : String "Username" : STRING(1024)
Tipo de clave Hash No corresponde
Otros campos Zipcode: Number Subscribed: Boolean ReminderDate: String PointsEarned: Number Zipcode: INT64 Subscribed: BOOL ReminderDate: DATE PointsEarned: INT64

Prepara la tabla de Amazon DynamoDB

En la siguiente sección, crearás una tabla de origen de Amazon DynamoDB y la propagarás con los datos.

  1. En Cloud Shell, crea una tabla de Amazon DynamoDB que use los atributos de la tabla de muestra.

    aws dynamodb create-table --table-name Migration \
        --attribute-definitions AttributeName=Username,AttributeType=S \
        --key-schema AttributeName=Username,KeyType=HASH \
        --provisioned-throughput ReadCapacityUnits=75,WriteCapacityUnits=75
    
  2. Verifica que el estado de la tabla sea ACTIVE.

    aws dynamodb describe-table --table-name Migration \
        --query 'Table.TableStatus'
    
  3. Propaga la tabla con los datos de muestra.

    python make-fake-data.py --table Migration --items 25000
    

Crea una base de datos de Cloud Spanner

Puedes crear una instancia de un solo nodo, apropiada para probar el alcance de este instructivo. Para la implementación de producción, consulta la documentación de las instancias de Cloud Spanner a fin de determinar el conteo de nodos adecuado y cumplir con los requisitos de rendimiento de tu base de datos.

En este ejemplo, crearás un esquema de tabla al mismo tiempo que la base de datos. También es posible y común llevar a cabo actualizaciones de esquemas después de crear la base de datos.

  1. Crea una instancia Cloud Spanner en la misma región en la que estableciste la zona predeterminada de Compute Engine. Por ejemplo, us-central1.

    gcloud spanner instances create spanner-migration \
        --config=regional-us-central1 --nodes=1 \
        --description="Migration Demo"
    
  2. Crea una base de datos en la instancia Cloud Spanner junto con la tabla de muestra.

    gcloud spanner databases create migrationdb \
        --instance=spanner-migration \
        --ddl "CREATE TABLE Migration ( \
                Username STRING(1024) NOT NULL, \
                PointsEarned INT64, \
                ReminderDate DATE, \
                Subscribed BOOL, \
                Zipcode INT64, \
             ) PRIMARY KEY (Username)"
    

Pon en pausa la base de datos

En las siguientes secciones, se muestra cómo exportar la tabla de origen de Amazon DynamoDB y establecer la replicación de Cloud Pub/Sub para capturar los cambios a la base de datos que ocurran durante la exportación. Si los cambios en la base de datos no son idempotentes y no es seguro escribir los mismos datos más de una vez, se recomienda seguir los siguientes pasos durante un período de mantenimiento en el que puedes pausar los cambios de la app a la tabla.

Cambios de transmisión a Cloud Pub/Sub

Usa una función de AWS Lambda para transmitir los cambios de la base de datos a Cloud Pub/Sub.

  1. En Cloud Shell, habilita las transmisiones de Amazon DynamoDB en tu tabla de origen.

    aws dynamodb update-table --table-name Migration \
        --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
    
  2. Configura un tema de Cloud Pub/Sub para recibir los cambios.

    gcloud pubsub topics create spanner-migration
    

    Aparece este resultado:

    $ gcloud pubsub topics create spanner-migration
    Created topic [projects/your-project/topics/spanner-migration].
    
  3. Crea una cuenta de servicio de Cloud IAM para insertar las actualizaciones de la tabla al tema de Cloud Pub/Sub.

    gcloud iam service-accounts create spanner-migration \
        --display-name="Spanner Migration"
    

    Aparece este resultado:

    $ gcloud iam service-accounts create spanner-migration --display-name="Spanner Migration"
    Created service account [spanner-migration].
    
  4. Crea una vinculación de política de Cloud IAM a fin de que la cuenta de servicio tenga el permiso para publicar en Cloud Pub/Sub. Reemplaza GOOGLE_CLOUD_PROJECT con el nombre de tu proyecto de GCP.

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --role roles/pubsub.publisher \
        --member serviceAccount:spanner-migration@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

    Aparece este resultado:

    $ gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --role roles/pubsub.publisher \
      --member serviceAccount:spanner-migration@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    bindings: (...truncated...) - members: - serviceAccount:spanner-migration@solution-z.iam.gserviceaccount.com role: roles/pubsub.publisher
  5. Crea las credenciales para la cuenta de servicio.

    gcloud iam service-accounts keys create credentials.json \
        --iam-account spanner-migration@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

    Aparece este resultado:

    $ gcloud iam service-accounts keys create credentials.json --iam-account spanner-migration@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    created key [5e559d9f6bd8293da31b472d85a233a3fd9b381c] of type [json] as [credentials.json] for [spanner-migration@your-project.iam.gserviceaccount.com]
  6. Prepara y empaqueta la función de AWS Lambda para insertar los cambios de la tabla de Amazon DynamoDB en el tema de Cloud Pub/Sub.

    pip install --ignore-installed --target=lambda-deps google-cloud-pubsub==0.35
    cd lambda-deps; zip -r9 ../pubsub-lambda.zip *; cd -
    zip -g pubsub-lambda.zip ddbpubsub.py
  7. Crea una variable para capturar los nombres de recursos de Amazon (ARN) de la función de ejecución de Lambda que creaste con anterioridad.

    LAMBDA_ROLE=$(aws iam list-roles \
        --query 'Roles[?RoleName==`dynamodb-spanner-lambda-role`].[Arn]' \
        --output text)
    
  8. Usa el paquete pubsub-lambda.zip para crear la función de AWS Lambda.

    aws lambda create-function --function-name dynamodb-spanner-lambda \
        --runtime python2.7 --role $LAMBDA_ROLE \
        --handler ddbpubsub.lambda_handler --zip fileb://pubsub-lambda.zip \
        --environment Variables="{SVCACCT=$(base64 -w 0 credentials.json),PROJECT=$GOOGLE_CLOUD_PROJECT,TOPIC=spanner-migration}"
    

    Aparece este resultado:

    $ aws lambda create-function --function-name dynamodb-spanner-lambda \
    >   --runtime python2.7 --role $LAMBDA_ROLE \
    >   --handler ddbpubsub.lambda_handler --zip fileb://pubsub-lambda.zip \
    >   --environment Variables="{SVCACCT=$(base64 -w 0 credentials.json),PROJECT=$GOOGLE_CLOUD_PROJECT,TOPIC=spanner-migration}"
    {
        "FunctionName": "dynamodb-spanner-lambda",
        "LastModified": "2018-07-07T12:53:58.670+0000",
        "RevisionId": "e58e8408-cd3a-4155-a184-4efc0da80bfb",
        "MemorySize": 128,
    ... truncated output...
  9. Crea una variable a fin de capturar la transmisión de ARN de Amazon DynamoDB para tu tabla.

    STREAMARN=$(aws dynamodb describe-table \
        --table-name Migration \
        --query "Table.LatestStreamArn" \
        --output text)
    
  10. Adjunta la función de Lambda a la tabla de Amazon DynamoDB.

    aws lambda create-event-source-mapping --event-source $STREAMARN \
        --function-name dynamodb-spanner-lambda --enabled \
        --starting-position TRIM_HORIZON
    
  11. Para optimizar la capacidad de respuesta durante la prueba, agrega --batch-size 1 al final del comando anterior que activa la función cada vez que creas, actualizas o borras un elemento.

    Aparece este resultado:

    $ aws lambda create-event-source-mapping --event-source $STREAMARN \
    >     --function-name dynamodb-spanner-lambda --enabled --starting-position TRIM_HORIZON
    {
        "UUID": "44e4c2bf-493a-4ba2-9859-cde0ae5c5e92",
        "StateTransitionReason": "User action",
        "LastModified": 1530662205.549,
        "BatchSize": 100,
        "EventSourceArn": "arn:aws:dynamodb:us-west-2:accountid:table/Migration/stream/2018-07-03T15:09:57.725",
        "FunctionArn": "arn:aws:lambda:us-west-2:accountid:function:dynamodb-spanner-lambda",
        "State": "Creating",
        "LastProcessingResult": "No records processed"
    }
    

Exporta la tabla de Amazon DynamoDB a Amazon S3

  1. En Cloud Shell, crea una variable para un nombre de depósito que usarás en varias de las siguientes secciones.

    BUCKET=$DEVSHELL_PROJECT_ID-dynamodb-spanner-export
    
  2. Crea un depósito de Amazon S3 para recibir la exportación de DynamoDB.

    aws s3 mb s3://$BUCKET
    
  3. En la Consola de administración de AWS, haz clic en Canalización de datos.

  4. Haz clic en Crear canalización nueva para definir el trabajo de exportación.

  5. En el campo Nombre, ingresa Exportar a Amazon S3.

  6. Para Origen, selecciona lo siguiente:

    • Compilar con una plantilla.
    • Exportar la tabla de DynamoDB a Amazon S3.
  7. En la sección Parámetros, define lo siguiente:

    1. En el campo Nombre de la tabla DynamoDB de origen, ingresa Migration.
    2. En el campo Carpeta S3 de salida, haz clic en el ícono Carpeta y selecciona el depósito de Amazon S3 [Your-Project-ID]-dynamodb-spanner-export que recién creaste, en que [YOUR-PROJECT-ID] representa el ID del proyecto de GCP.
    3. Para consumir toda la capacidad de lectura disponible durante la exportación, en el campo Índice de capacidad de procesamiento de lectura de DynamoDB, ingresa 1. En un entorno de producción, define este valor para no dificultar las operaciones en vivo.
    4. En el campo Región de tu tabla de DynamoDB, ingresa el nombre de la región, por ejemplo, us-west-2.
  8. Para iniciar de inmediato los trabajos de copia de seguridad, en la sección Programar de ejecutar, haz clic en Activación de canalización.

  9. En Configuración de canalización, en el campo Registro, ingresa Disabled. Si sigues esta guía con el objetivo de migrar una tabla de producción, deja esta opción habilitada y que apunte a un depósito Amazon S3 separado para que los registros te ayuden a solucionar errores. Deja los otros parámetros predeterminados.

  10. Para inicial el proceso de copia de seguridad, haz clic en Activar.

  11. Si se te pide que dirijas advertencias de validación, haz clic en Activar. En una situación de producción, establece una duración máxima para el trabajo y habilita el registro.

  12. Haz clic en Actualizar para que se actualice el estado del proceso de la copia de seguridad. Este trabajo puede tardar varios minutos en crear los recursos y finalizar la exportación. En un entorno de producción, puedes acelerar este proceso si modificas los trabajos de Canalización de datos para usar más recursos EMR.

    En el momento que el proceso finaliza, revisa el depósito de salida.

    aws s3 ls --recursive s3://$BUCKET
    

    El trabajo de exportación finaliza cuando aparece un archivo con el nombre _SUCCESS.

    $ aws s3 ls --recursive s3://$BUCKET
    
    2018-06-30 13:08:11 3736518 2018-06-30-20-01-21/76b53eea-46d1-4293-ba51-11759f5c65fa
    2018-06-30 13:08:20       0 2018-06-30-20-01-21/_SUCCESS
    2018-06-30 13:08:20     178 2018-06-30-20-01-21/manifest
    

Abre la base de datos

Si pausas las operaciones de escritura en la base de datos antes de la exportación, reactiva las operaciones de escritura en la base de datos. Una vez que la publicación de Cloud Pub/Sub está en su lugar, puedes seguir adelante con cualquier cambio en la tabla generado después de la exportación.

Copia la tabla exportada a Cloud Storage

  1. En Cloud Shell, crea un depósito de Cloud Storage para recibir los archivos exportados de Amazon S3.

    gsutil mb gs://$BUCKET
    
  2. Sincroniza los archivos de Amazon S3 en Cloud Storage. Para la mayoría de las operaciones de copia, el comando rsync es eficaz. Si tus archivos de exportación son grandes (de varios GB o más), usa el Servicio de transferencia de Cloud Storage para administrar la transferencia en segundo plano.

    gsutil rsync -d -r s3://$BUCKET gs://$BUCKET
    

    Aparece este resultado:

    $ gsutil rsync -d -r s3://$BUCKET gs://$BUCKET
    Building synchronization state...
    Starting synchronization...
    Copying s3://project-dynamodb-spanner-export/2018-06-30-20-01-21/76b53eea-46d1-4293-ba51-11759f5c65fa [Content-Type=binary/octet-stream]...
    Copying s3://project-dynamodb-spanner-export/2018-06-30-20-01-21/_SUCCESS [Content-Type=binary/octet-stream]...
    Copying s3://project-dynamodb-spanner-export/2018-06-30-20-01-21/manifest [Content-Type=binary/octet-stream]...
    / [3 files][  3.6 MiB/  3.6 MiB]
    Operation completed over 3 objects/3.6 MiB.
    

Importa los datos por lotes

  1. Para escribir los datos de los archivos exportados en la tabla de Cloud Spanner, ejecuta un trabajo de Cloud Dataflow con un código Apache Beam de muestra.

    cd dataflow
    mvn compile
    mvn exec:java \
        -Dexec.mainClass=com.example.spanner_migration.SpannerBulkWrite \
        -Dexec.args="--project=$GOOGLE_CLOUD_PROJECT \
                     --instanceId=spanner-migration \
                     --databaseId=migrationdb \
                     --table=Migration \
                     --importBucket=$BUCKET \
                     --runner=dataflow"
    
    1. Ve a Cloud Dataflow en GCP Console para mirar el progreso del trabajo de importación.

      IR A Cloud Dataflow

    2. Mientras se ejecuta el trabajo, puedes mirar el grafo de ejecución para examinar los registros. Haz clic en el trabajo que muestra el Estado de ejecución.

      Cómo ejecutar un trabajo de importación

  2. Haz clic en cada etapa para ver cuántos elementos se procesaron. La importación se completa cuando todas las etapas dicen Se realizó con éxito. La misma cantidad de elementos que se crearon en tu tabla Amazon DynamoDB se muestran como procesados en cada etapa.

    Etapas de correctas del trabajo de importación

  3. Verifica que la cantidad de registros en la tabla de Cloud Spanner de destino coincida con la cantidad de elementos en la tabla de Amazon DynamoDB.

    aws dynamodb describe-table --table-name Migration --query Table.ItemCount
    gcloud spanner databases execute-sql migrationdb \ --instance=spanner-migration --sql="select count(*) from Migration"

    Aparece este resultado:

    $ aws dynamodb describe-table --table-name Migration --query Table.ItemCount
    25000
    $ gcloud spanner databases execute-sql migrationdb --instance=spanner-migration --sql="select count(*) from Migration"
    25000
    
  4. Muestra entradas aleatorias en cada tabla para asegurar de que los datos sean coherentes.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="select * from Migration limit 1"
    

    Aparece este resultado:

    $ gcloud spanner databases execute-sql migrationdb --instance=spanner-migration --sql="select * from Migration limit 1"
    Username    PointsEarned  ReminderDate  Subscribed  Zipcode
    aallen2538  1606          2018-06-18    False       17303
    
  5. Consulta la tabla de Amazon DynamoDB con el mismo Username que se mostró desde la consulta de Cloud Spanner en el paso anterior. Por ejemplo, aallen2538. Tu valor es específico al de tu base de datos.

    aws dynamodb get-item --table-name Migration \
        --key '{"Username": {"S": "aallen2538"}}'
    

    Los valores de los otros campos deben coincidir con los del resultado de Cloud Spanner. Aparece este resultado:

    $ aws dynamodb get-item --table-name Migration --key '{"Username": {"S": "aallen2538"}}'
    {
        "Item": {
            "Username": {
                "S": "aallen2538"
            },
            "ReminderDate": {
                "S": "2018-06-18"
            },
            "PointsEarned": {
                "N": "1606"
            },
            "Zipcode": {
                "N": "17303"
            },
            "Subscribed": {
                "BOOL": false
            }
        }
    }
    

Repite los cambios nuevos

Cuando la importación por lotes finaliza, configura un trabajo de transmisión para escribir las actualizaciones en curso de la tabla de origen a Cloud Spanner. Suscríbete a los eventos desde Cloud Pub/Sub y escribe en Cloud Spanner

La función Lambda que creaste se configura para capturar los cambios en la tabla de Amazon DynamoDB de origen y, luego, publícalos en Cloud Pub/Sub.

  1. Crea una suscripción al tema de Cloud Pub/Sub al que AWS Lambda envía eventos.

    gcloud pubsub subscriptions create spanner-migration \
        --topic spanner-migration
    

    Aparece este resultado:

    $ gcloud pubsub subscriptions create spanner-migration --topic spanner-migration
    Created subscription [projects/your-project/subscriptions/spanner-migration].
    
  2. Para transmitir los datos que ingresan a Cloud Pub/Sub y escribir la tabla de Cloud Spanner, ejecuta el trabajo de Cloud Dataflow desde Cloud Shell.

    cd ~/dynamodb-spanner-migration/dataflow
    mvn exec:java \
        -Dexec.mainClass=com.example.spanner_migration.SpannerStreamingWrite \
        -Dexec.args="--project=$GOOGLE_CLOUD_PROJECT \
                     --instanceId=spanner-migration \
                     --databaseId=migrationdb \
                     --table=Migration \
                     --experiments=allow_non_updatable_job \
        --subscription=projects/$GOOGLE_CLOUD_PROJECT/subscriptions/spanner-migration"
    
    1. Al igual que el paso de la carga por lotes, ve a Cloud Dataflow en GCP Console para ver el progreso del trabajo.

      IR A Cloud Dataflow

    2. Haz clic en el trabajo que tenga el Estado de ejecución.

      Cómo ejecutar un trabajo

      El grafo de procesamiento muestra una salida similar a la anterior, pero cada elemento procesado se cuenta en la ventana de estado. El tiempo de retardo del sistema es un cálculo aproximado de cuánto esperar antes de que los cambios aparezcan en la tabla de Cloud Spanner.

      Cómo ejecutar los procesos debido al tiempo de retraso

El trabajo de Cloud Dataflow que ejecutaste en la fase de carga por lotes era un conjunto finito de entradas, también conocido como un conjunto de datos delimitado. Este trabajo de Cloud Dataflow usa Cloud Pub/Sub como una fuente de transmisión y se considera ilimitado. Para obtener más información sobre estos dos tipos de fuentes, consulta la sección sobre PCollections en la guía de programación Apache Beam. El trabajo de Cloud Dataflow en este paso está pensado para permanecer activo, por lo que no termina cuando finaliza. El trabajo Cloud Dataflow de transmisión permanece en el estado Ejecución, en lugar del estado Se realizó con éxito.

Verifica la replicación

Puedes hacer algunos cambios a la tabla de origen para verificar que se repliquen en la tabla de Cloud Spanner.

  1. Consulta una fila no existente en Cloud Spanner.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration --sql=\
        "SELECT * FROM Migration WHERE Username='my-test-username'"
    
  2. Crea un registro en Amazon DynamoDB con la misma clave que usaste en la consulta de Cloud Spanner. Si el comando se ejecuta de forma correcta, no hay resultado.

    aws dynamodb put-item \
        --table-name Migration \
        --item '{"Username" : {"S" : "my-test-username"}, "Subscribed" : {"BOOL" : false}}'
    
  3. Ejecuta la consulta original otra vez para verificar que la fila esté ahora en Cloud Spanner.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

    El resultado muestra la fila que se insertó:

    $ gcloud spanner databases execute-sql migrationdb --instance=spanner-migration --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    Username PointsEarned ReminderDate Subscribed Zipcode my-test-username None None False
  4. Cambia algunos atributos en el elemento original y actualiza la tabla Amazon DynamoDB.

    aws dynamodb update-item \
        --table-name Migration \
        --key '{"Username": {"S":"my-test-username"}}' \
        --update-expression "SET PointsEarned = :pts, Subscribed = :sub" \
        --expression-attribute-values '{":pts": {"N":"4500"}, ":sub": {"BOOL":true}}'\
        --return-values ALL_NEW
    

    El resultado aparece de la siguiente manera:

    $ aws dynamodb update-item \
    >   --table-name Migration \
    >   --key '{"Username": {"S":"my-test-username"}}' \
    >   --update-expression "SET PointsEarned = :pts, Subscribed = :sub" \
    >   --expression-attribute-values '{":pts": {"N":"4500"}, ":sub": {"BOOL":true}}'\
    >   --return-values ALL_NEW
    {
        "Attributes": {
            "Username": {
                "S": "my-test-username"
            },
            "PointsEarned": {
                "N": "4500"
            },
            "Subscribed": {
                "BOOL": true
            }
        }
    }
    
  5. Verifica que los cambios se propaguen a la tabla Cloud Spanner.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

    El resultado aparece de la siguiente manera:

    $ gcloud spanner databases execute-sql migrationdb --instance=spanner-migration --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    Username PointsEarned ReminderDate Subscribed Zipcode my-test-username 4500 None True
  6. Borra el elemento de prueba de la tabla de origen Amazon DynamoDB.

    aws dynamodb delete-item \
        --table-name Migration \
        --key '{"Username": {"S":"my-test-username"}}'
    
  7. Verifica que la fila correspondiente se borre de la tabla Cloud Spanner. Cuando se propaga el cambio, el siguiente comando no muestra filas:

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration \
        --sql="SELECT * FROM Migration WHERE Username='my-test-username'"
    

Usa las tablas intercaladas

Cloud Spanner es compatible con el concepto de tablas intercaladas. Este es un modelo de diseño en el que un elemento de nivel superior tiene varios elementos anidados que se relacionan con ese elemento de nivel superior, como un cliente y sus pedidos o un jugador y sus puntuaciones de juego. Si tu tabla de origen Amazon DynamoDB usa una clave primaria que consta de una clave hash y una clave de rango, puedes modelar un esquema de tabla intercalada como se muestra en el siguiente diagrama. Esta estructura permite consultar de manera eficaz la tabla intercalada mientras unes los campos en la tabla superior.

Tabla de usuarios comparadas con tablas de pedidos

Aplica índices secundarios

Se recomienda aplicar índices secundarios a las tablas de Cloud Spanner después de cargar los datos. Ahora que la replicación funciona, configura un índice secundario para acelerar las solicitudes. Al igual que las tablas de Cloud Spanner, los índices secundarios de Cloud Spanner son 100% coherentes. No tienen coherencia eventual, que es usual en muchas bases de datos NoSQL. Esta característica puede ayudarte a simplificar el diseño de tu app.

Ejecuta una consulta que no use ningún índice. Busca los casos N superiores, especificados con un valor de columna particular. Esta es una consulta común en Amazon DynamoDB para la eficiencia de la base de datos.

  1. Ve a Cloud Spanner.

    IR A Cloud Spanner

  2. Haz clic en CONSULTA.

    Botón de consulta

  3. En el campo Consulta, ingresa la siguiente consulta y, a continuación, haz clic en Ejecutar consulta.

    SELECT Username,PointsEarned FROM Migration
      WHERE Subscribed=true AND
      ReminderDate > DATE_SUB(DATE(current_timestamp()), INTERVAL 3 DAY)
    

    Luego de ejecutar la consulta, haz clic en Explicación y toma nota de las Filas analizadas en comparación con las Filas mostradas. Sin un índice, Cloud Spanner analiza toda la tabla para mostrar un pequeño subconjunto de datos que coincida con la consulta.

    Filas analizadas comparadas con filas mostradas

  4. Si esto representa una consulta común, crea un índice compuesto en las columnas suscritas y fecha de aviso. En la consola de Cloud Spanner, haz clic en Crear índice.

  5. Haz clic para activar Editar como texto.

  6. En las Declaraciones de DDL, ingresa la definición del índice.

    CREATE INDEX SubscribedDate
    ON Migration (
      Subscribed,
      ReminderDate
    )
    
  7. Para comenzar a recopilar la base de datos en segundo plano, haz clic en Crear.

    Actualización de esquema en curso

  8. Después de crear el índice, vuelve a ejecutar la consulta y agrega el índice.

    SELECT Username,PointsEarned FROM
    Migration@{FORCE_INDEX=SubscribedDate}
      WHERE Subscribed=true AND
      ReminderDate > DATE_SUB(DATE(current_timestamp()), INTERVAL 3 DAY)
    

    Vuelve a examinar la explicación de consulta. Ten en cuenta que la cantidad de Filas analizadas ha disminuido. Las Filas mostradas en cada paso coinciden con la cantidad que mostró la consulta.

    Explicación de la consulta

Índices intercalados

Puedes configurar los índices intercalados en Cloud Spanner. Los índices secundarios en la sección anterior están en la raíz de la jerarquía de la base de datos y usan los índices de la misma forma que una base de datos convencional. Un índice intercalado está en el contexto de su fila intercalada. Consulta Opciones de índice para obtener más detalles acerca de dónde aplicar los índices intercalados.

Ajusta tu modelo de datos

Modifica tus archivos de origen de Apache Beam para adaptar la parte de la migración de este instructivo a tu propia situación. Lo importante es que no cambies el esquema de origen durante la ventana de migración real, de lo contrario puedes perder los datos.

  1. Con el objetivo de analizar el JSON entrante y compilar mutaciones, usa GSON. Ajusta la definición JSON para que coincida con tus datos.

    public static class Item implements Serializable {
        private Username Username;
        private PointsEarned PointsEarned;
        private Subscribed Subscribed;
        private ReminderDate ReminderDate;
        private Zipcode Zipcode;
    
    }
    
    public static class Username implements Serializable {
        private String s;
    
    }
    
    public static class PointsEarned implements Serializable {
        private String n;
    
    }
    
    public static class Subscribed implements Serializable {
        private String bOOL;
    
    }
    
    public static class ReminderDate implements Serializable {
        private String s;
    
    }
    
    public static class Zipcode implements Serializable {
        private String n;
    
    }
  2. Define la asignación JSON correspondiente.

    mutation.set("Username").to(item.Username.s);
    
    Optional.ofNullable(item.Zipcode).ifPresent(x->{
        mutation.set("Zipcode").to(Integer.parseInt(x.n));
    });
    
    Optional.ofNullable(item.Subscribed).ifPresent(x->{
        mutation.set("Subscribed").to(Boolean.parseBoolean(x.bOOL));
    });
    
    Optional.ofNullable(item.ReminderDate).ifPresent(x->{
        mutation.set("ReminderDate").to(Date.parseDate(x.s));
    });
    
    Optional.ofNullable(item.PointsEarned).ifPresent(x->{
        mutation.set("PointsEarned").to(Integer.parseInt(x.n));
    });

En los pasos anteriores, modificaste el código fuente de Apache Beam para la importación masiva. Modifica el código fuente para la parte de transmisión de la canalización de una manera similar. Por último, ajusta la secuencia de comandos de creación de tablas, índices y esquemas de tu base de destino de Cloud Spanner.

Limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

Borra el proyecto

  1. En la GCP Console, dirígete a la página Proyectos.

    Ir a la página Proyectos

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

Borra los recursos de AWS

Si tu cuenta de AWS se usa por fuera de este instructivo, ten cuidado cuando borres los siguientes recursos:

  1. Borra la tabla de DynamoDB llamada Migración.
  2. Borra el depósito de Amazon S3 y la función de Lambda que creaste durante los pasos de migración.
  3. Por último, borra el usuario de IAM de AWS que creaste durante este instructivo.

Pasos siguientes

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...