Migra de DynamoDB a Cloud Spanner

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

En este instructivo, se da por sentado que conoces los esquemas de base de datos, los tipos de datos, los aspectos principales de NoSQL y los sistemas de bases de datos relacionales. 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 Spanner
  • Crear una tabla de migración y base de datos de Spanner
  • 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 Dataflow para cargar datos en Spanner

Costos

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

  • GKE
  • Pub/Sub
  • Cloud Storage
  • Dataflow

Los cargos de Spanner se calculan según la cantidad de horas de procesamiento de 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, calcula tus requisitos de almacenamiento y capacidad de procesamiento. A continuación, usa la documentación de instancias de Spanner a fin de determinar la cantidad de nodos que necesitas.

Además de los recursos de Google Cloud, 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.

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 sean aptos para obtener 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. En la página de selección de proyectos de Cloud Console, selecciona o crea un proyecto de Cloud.

    Ir a la página Selector de proyectos

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

    Descubre cómo puedes habilitar la facturación

  4. Habilita las API de Spanner, Pub/Sub, Compute Engine, and Dataflow.

    Habilita las API

Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta cómo hacer una limpieza.

Prepara tu entorno

En este instructivo, ejecutarás comandos en Cloud Shell. Cloud Shell te brinda acceso a la línea de comandos en Google Cloud y, además, incluye el SDK de Cloud y otras herramientas que necesitas para el desarrollo de Google Cloud. 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 IAM, haz clic en Funciones y, luego, 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 la casilla Tipo de política, ingresa AWSLambdaDynamoDBExecutionRole.
  4. Selecciona la casilla de verificación AWSLambdaDynamoDBExecutionRole y, luego, haz clic en Siguiente: Revisar.
  5. En la casilla Nombre de 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 IAM de la consola de AWS, haz clic en Usuarios y, a continuación, selecciona Agregar usuario.
  2. En la casilla 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
    

    Aparecerá 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 la SECRET ACCESS KEY de la cuenta 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.

Obtén información sobre 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 Spanner.

Tipos de datos

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

Amazon DynamoDB 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 de Amazon DynamoDB cuya clave primaria es una clave hash. Esta clave hash se convierte en la clave primaria de tu tabla de 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 Spanner admiten la creación de un índice en un atributo que no es una clave primaria. Toma nota de los índices secundarios de la tabla de Amazon DynamoDB para poder crearlos en la tabla de Spanner, proceso que se explica en una sección posterior de este instructivo.

Tabla de muestra

Para que este instructivo sea más sencillo de comprender, migra la siguiente tabla de muestra de Amazon DynamoDB a Spanner:

Amazon DynamoDB 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 Spanner

Puedes crear una instancia de un solo nodo, apropiada para probar el alcance de este instructivo. Con el fin de llevar a cabo una implementación de producción, consulta la documentación sobre instancias de Spanner a fin de determinar el recuento de nodos adecuado para 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 de Spanner en la misma región en la que estableciste la zona de Compute Engine predeterminada. 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 de 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 configurar la replicación de Pub/Sub para registrar cualquier cambio en la base de datos que ocurra mientras la exportas. 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 estos pasos durante un período de mantenimiento en el que puedes pausar los cambios de la app a la tabla.

Transmite cambios a Pub/Sub

Usa una función de AWS Lambda para transmitir los cambios de la base de datos a 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 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 IAM para enviar actualizaciones de tabla al tema de 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 IAM a fin de que la cuenta de servicio tenga permiso para publicar en Pub/Sub. Reemplaza GOOGLE_CLOUD_PROJECT por el nombre del proyecto de Google Cloud.

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

    Aparecerá 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
    

    Aparecerá 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 enviar los cambios de la tabla de Amazon DynamoDB al tema de 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 antes.

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

    Aparecerá 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 las pruebas, agrega --batch-size 1 al final del comando anterior, que activa la función cada vez que creas, actualizas o borras un elemento.

    Aparecerá 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 tabla de origen de DynamoDB, ingresa Migration.
    2. En el campo Carpeta de salida de S3, haz clic en el ícono Carpeta y selecciona el depósito de Amazon S3 [Your-Project-ID]-dynamodb-spanner-export que acabas de crear; en este caso, [YOUR-PROJECT-ID] representa tu ID del proyecto de Google Cloud.
    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 la 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 Activar 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 haz que apunte a un depósito Amazon S3 individual 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 en el 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 pausaste 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 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
    

    Aparecerá 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 Spanner, ejecuta un trabajo de Dataflow con un código de muestra de Apache Beam.

    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. Para ver el progreso del trabajo de importación, ve a Dataflow.

      IR A Dataflow

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

      Ejecuta 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 de Amazon DynamoDB se muestran como procesados en cada etapa.

    Etapas del trabajo de importación llevadas a cabo con éxito

  3. Verifica que la cantidad de registros en la tabla de destino de Spanner 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"

    Aparecerá 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"
    

    Aparecerá 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ó en la consulta de Spanner del paso anterior. Por ejemplo, aallen2538. Tu valor es específico 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 Spanner. Aparecerá 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
            }
        }
    }
    

Replica los cambios nuevos

Cuando se completa el trabajo de importación por lotes, configura un trabajo de transmisión para escribir actualizaciones continuas de la tabla de origen en Spanner. Te suscribes a los eventos de Pub/Sub y los escribes en Spanner

La función de Lambda que creaste está configurada para registrar los cambios en la tabla de origen de Amazon DynamoDB y publicarlos en Pub/Sub.

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

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

    Aparecerá este resultado:

    $ gcloud pubsub subscriptions create spanner-migration --topic spanner-migration
    Created subscription [projects/your-project/subscriptions/spanner-migration].
    
  2. Para transmitir los cambios que ingresan a Pub/Sub y escribir la tabla de Spanner, ejecuta el trabajo de 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. De manera similar al paso de carga por lotes, para ver el progreso del trabajo, ve a Dataflow en Cloud Console.

      IR A Dataflow

    2. Haz clic en el trabajo cuyo Estado sea En ejecución.

      Ejecuta un trabajo

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

      Ejecuta los procesos debido al tiempo de demora

El trabajo de 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 Dataflow usa 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 de Apache Beam. El trabajo de Dataflow en este paso está destinado a permanecer activo, por lo que no se finaliza cuando termina de procesarse. El trabajo de transmisión de Dataflow permanece en el estado En ejecución, en lugar del estado Se realizó con éxito.

Verifica la replicación

Realiza algunos cambios en la tabla de origen para verificar que los cambios se repliquen en la tabla de Spanner.

  1. Consulta una fila no existente en 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 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. Vuelve a ejecutar la consulta original para verificar que la fila esté ahora en Spanner.

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

    En el resultado se 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 en la tabla de 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 de 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 de 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

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 comparada con tabla de pedidos

Aplica índices secundarios

Se recomienda aplicar índices secundarios a las tablas de 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 Spanner, los índices secundarios de 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 Spanner.

    IR A Spanner

  2. Haz clic en CONSULTA (QUERY).

    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, 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 Subscribed y ReminderDate. En la consola de 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 compilar 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 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 JSON entrante y compilar mutaciones, usa GSON. Ajusta la definición de 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 datos de destino de Spanner.

Realiza una 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 Cloud Console, ve a la página Administrar recursos.

    Ir a la página Administrar recursos

  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 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.

Próximos pasos