Como migrar do DynamoDB para o Cloud Spanner

Neste tutorial, descrevemos como migrar do Amazon DynamoDB para o Cloud Spanner. Ele é destinado principalmente aos proprietários de aplicativos que querem migrar de um sistema NoSQL para o Cloud Spanner, um sistema de banco de dados SQL totalmente relacional, tolerante a falhas e altamente escalonável que oferece suporte a transações. Se você tiver um uso consistente da tabela do Amazon DynamoDB, em termos de tipos e layout, o mapeamento para o Cloud Spanner será direto. Se as tabelas do Amazon DynamoDB contiverem tipos e valores de dados arbitrários, talvez seja mais simples migrar para outros serviços NoSQL, como o Cloud Datastore ou o Firebase.

Neste tutorial, pressupomos que você tenha familiaridade com esquemas de banco de dados, tipos de dados, os fundamentos do NoSQL e sistemas de bancos de dados relacionais. O tutorial depende da execução de tarefas predefinidas para realizar uma migração de amostra. Após o tutorial, é possível modificar o código e as etapas fornecidas para corresponder ao seu ambiente.

O seguinte diagrama arquitetural descreve os componentes usados no tutorial para migrar dados:

Diagrama arquitetural dos componentes de migração

Objetivos

  • Migrar dados do Amazon DynamoDB para o Cloud Spanner.
  • Criar um banco de dados e uma tabela de migração do Cloud Spanner.
  • Mapear um esquema NoSQL em um esquema relacional.
  • Criar e exportar um conjunto de dados de amostra que use o Amazon DynamoDB.
  • Transferir dados entre o Amazon S3 e o Cloud Storage.
  • Usar o Cloud Dataflow para carregar dados no Cloud Spanner.

Custos

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

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

As cobranças do Cloud Spanner baseiam-se no número de horas dos nós e na quantidade de dados armazenados durante o ciclo de faturamento mensal. Durante o tutorial, você usa uma configuração mínima desses recursos, que são limpos no final. Para cenários reais, estime seus requisitos de capacidade e armazenamento e, em seguida, use a documentação de instâncias do Cloud Spanner para determinar o número de nós necessários.

Além dos recursos do GCP, este tutorial usa os seguintes recursos da Amazon Web Services (AWS):

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

Esses serviços são necessários apenas durante o processo de migração. No final do tutorial, siga as instruções para limpar todos os recursos e evitar cobranças desnecessárias. Use a calculadora de preços da AWS para estimar esses custos.

Use a calculadora de preços para gerar uma estimativa de custo com base no uso do projeto. Novos usuários do GCP são qualificados para uma avaliação gratuita.

Antes de começar

  1. Faça login na sua Conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. Selecione ou crie um projeto do Google Cloud Platform.

    Acessar a página Gerenciar recursos

  3. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform.

    Saiba como ativar o faturamento

  4. Ativar Cloud Spanner, Cloud Pub/Sub, Compute Engine, and Cloud Dataflow APIs.

    Ativar as APIs

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

Como preparar o ambiente

Neste tutorial, você executa comandos no Cloud Shell. O Cloud Shell fornece acesso à linha de comando no GCP e inclui o SDK do Cloud e outras ferramentas necessárias para o desenvolvimento do GCP. O Cloud Shell pode demorar vários minutos para ser inicializado.

  1. Ative o Cloud Shell.

    ATIVAR o Cloud Shell

  2. Defina a zona padrão do Compute Engine. Por exemplo: us-central1-b.

    gcloud config set compute/zone us-central1-b
    
  3. Clone o repositório do GitHub que contém o código de amostra.

    git clone https://github.com/GoogleCloudPlatform/dynamodb-spanner-migration.git
    
  4. Acesse o diretório clonado.

    cd dynamodb-spanner-migration
    
  5. Crie um ambiente virtual em Python.

    virtualenv --python python2 env
    
  6. Ative o ambiente virtual.

    source env/bin/activate
    
  7. Instale os módulos necessários do Python.

    pip install -r requirements.txt
    

Como configurar o acesso da AWS

Neste tutorial, você cria e exclui tabelas do Amazon DynamoDB, intervalos do Amazon S3 e outros recursos. Para acessar esses recursos, primeiro você precisa criar as permissões exigidas pelo AWS Identity and Access Management (IAM). Use uma conta de teste ou sandbox da AWS para evitar afetar os recursos de produção na mesma conta.

Criar uma função do AWS IAM para o AWS Lambda

Nesta seção, você cria uma função do AWS IAM que o AWS Lambda usa em uma etapa posterior do tutorial.

  1. No console da AWS, acesse a seção IAM, clique em Roles e selecione Create role.
  2. Em Choose the service that will use this role, clique em Lambda e, em seguida, selecione Next:Permissions.
  3. Na caixa Policy Type, digite AWSLambdaDynamoDBExecutionRole.
  4. Marque a caixa de seleção AWSLambdaDynamoDBExecutionRole e clique em Next:Review.
  5. Na caixa Role name, digite dynamodb-spanner-lambda-role e, em seguida, clique em Create role.

Criar um usuário do AWS IAM

Siga estas etapas para criar um usuário do AWS IAM com acesso programático aos recursos da AWS, que são usados em todo o tutorial.

  1. Enquanto você ainda estiver na seção IAM do console da AWS, clique em Users e selecione Add User.
  2. Na caixa User name, digite dynamodb-spanner-migration.
  3. Em Access type, clique em Programmatic access.

  4. Clique em Next: Permissions.

  5. Clique em Attach existing policies directly e selecione as duas políticas a seguir:

    • AmazonDynamoDBFullAccesswithDataPipeline
    • AmazonS3FullAccess
  6. Clique em Next: Review e, em seguida, clique em Create user.

  7. Clique em Show para ver as credenciais. O ID da chave de acesso e a chave de acesso secreta são exibidos para o usuário recém-criado. Deixe essa janela aberta por enquanto porque as credenciais são necessárias na seção a seguir. Armazene com segurança essas credenciais porque com elas é possível fazer alterações em sua conta e afetar seu ambiente. No final deste tutorial, exclua o usuário do IAM.

Configurar a interface da linha de comando da AWS

  1. No Cloud Shell, configure a interface da linha de comando (CLI, na sigla em inglês) da AWS.

    aws configure
    

    A seguinte resposta é exibida:

    $ 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$
    
    • Insira ACCESS KEY ID e SECRET ACCESS KEY da conta do AWS IAM que criou.
    • No campo Default region name, insira us-west-2. Deixe outros campos com seus valores padrão.
  2. Feche a janela do console do AWS IAM.

Como entender o modelo de dados

Na seção a seguir, descrevemos as semelhanças e diferenças entre tipos de dados, chaves e índices para o Amazon DynamoDB e o Cloud Spanner.

Tipos de dados

O Cloud Spanner usa tipos de dados SQL padrão. A tabela a seguir descreve como os tipos de dados do Amazon DynamoDB se relacionam com os tipos de dados do Cloud Spanner.

Amazon DynamoDB Cloud Spanner
Número Dependendo da precisão ou uso pretendido, pode ser mapeado como INT64, FLOAT64, TIMESTAMP ou DATE.
String String
Booleano BOOL
Nulo Nenhum tipo explícito. Colunas podem conter valores nulos.
Binário Bytes
Conjuntos Matriz
Mapa e lista Struct se a estrutura for consistente e puder ser descrita usando a sintaxe da tabela DDL.

Chave primária

Uma chave primária do Amazon DynamoDB estabelece exclusividade e pode ser uma chave de hash ou uma combinação de uma chave de hash, além de uma chave de intervalo. Este tutorial inicia modelando a migração de uma tabela do Amazon DynamoDB em que a chave primária é uma chave de hash. Essa chave de hash se torna a chave primária da sua tabela do Cloud Spanner. Posteriormente, na seção sobre tabelas intercaladas, você modela uma situação em que uma tabela do Amazon DynamoDB usa uma chave primária composta de uma chave de hash e uma chave de intervalo.

Índices secundários

O Amazon DynamoDB e o Cloud Spanner oferecem suporte à criação de um índice em um atributo de chave não primária. Anote os índices secundários na sua tabela do Amazon DynamoDB para que possa criá-los na sua tabela do Cloud Spanner, que será abordada em uma seção posterior deste tutorial.

Tabela de amostra

Para facilitar este tutorial, migre a seguinte tabela de amostra do Amazon DynamoDB para o Cloud Spanner:

Amazon DynamoDB Cloud Spanner
Nome da tabela Migration Migration
Chave primária "Username" : String "Username" : STRING(1024)
Tipo de chave Hash n/a
Outros campos Zipcode: Number Subscribed: Boolean ReminderDate: String PointsEarned: Number Zipcode: INT64 Subscribed: BOOL ReminderDate: DATE PointsEarned: INT64

Como preparar a tabela do Amazon DynamoDB

Na seção a seguir, você cria uma tabela de origem do Amazon DynamoDB e a preenche com dados.

  1. No Cloud Shell, crie uma tabela do Amazon DynamoDB que use os atributos da tabela de amostra.

    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. Verifique se o status da tabela é ACTIVE.

    aws dynamodb describe-table --table-name Migration \
        --query 'Table.TableStatus'
    
  3. Preencha a tabela com dados de amostra.

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

Como criar um banco de dados do Cloud Spanner

Você cria uma instância de nó único, que é apropriada para testes e o escopo deste tutorial. Para uma implantação de produção, consulte a documentação das instâncias do Cloud Spanner para determinar a contagem de nós apropriada para atender aos requisitos de desempenho do seu banco de dados.

Neste exemplo, você cria um esquema de tabela ao mesmo tempo que o banco de dados. Também é possível (e comum) realizar atualizações de esquema depois de criar o banco de dados.

  1. Crie uma instância do Cloud Spanner na mesma região em que você definir a zona padrão do Compute Engine. Por exemplo: us-central1.

    gcloud spanner instances create spanner-migration \
        --config=regional-us-central1 --nodes=1 \
        --description="Migration Demo"
    
  2. Crie um banco de dados na instância do Cloud Spanner junto com a tabela de amostra.

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

Como pausar o banco de dados

As próximas seções mostram como exportar a tabela de origem do Amazon DynamoDB e configurar a replicação do Cloud Pub/Sub para capturar quaisquer alterações no banco de dados que ocorrerem enquanto você o exporta. Se as alterações em seu banco de dados não forem idempotentes e não for seguro gravar os mesmos dados mais de uma vez, é melhor executar as etapas a seguir durante um período de manutenção, quando é possível pausar as alterações do aplicativo na tabela.

Transmitir alterações para o Cloud Pub/Sub

Você usa uma função do AWS Lambda para transmitir alterações do banco de dados para o Cloud Pub/Sub.

  1. No Cloud Shell, ative os fluxos do Amazon DynamoDB na sua tabela de origem.

    aws dynamodb update-table --table-name Migration \
        --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
    
  2. Configure um tópico do Cloud Pub/Sub para receber as alterações.

    gcloud pubsub topics create spanner-migration
    

    A seguinte resposta é exibida:

    $ gcloud pubsub topics create spanner-migration
    Created topic [projects/your-project/topics/spanner-migration].
    
  3. Crie uma conta de serviço do Cloud IAM para enviar atualizações da tabela para o tópico do Cloud Pub/Sub.

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

    A seguinte resposta é exibida:

    $ gcloud iam service-accounts create spanner-migration --display-name="Spanner Migration"
    Created service account [spanner-migration].
    
  4. Crie uma vinculação de política do Cloud IAM para que a conta de serviço tenha permissão para publicar no Cloud Pub/Sub. Substitua GOOGLE_CLOUD_PROJECT pelo nome do seu projeto do GCP.

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

    A seguinte resposta é exibida:

    $ 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. Crie credenciais para a conta de serviço.

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

    A seguinte resposta é exibida:

    $ 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. Prepare e empacote a função do AWS Lambda para enviar as alterações da tabela do Amazon DynamoDB para o tópico do 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. Crie uma variável para capturar o Nome de Recurso da Amazon (ARN na sigla em inglês) da função de execução do Lambda que você criou anteriormente.

    LAMBDA_ROLE=$(aws iam list-roles \
        --query 'Roles[?RoleName==`dynamodb-spanner-lambda-role`].[Arn]' \
        --output text)
    
  8. Use o pacote pubsub-lambda.zip para criar a função do 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}"
    

    A seguinte resposta é exibida:

    $ 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. Crie uma variável para capturar o ARN do fluxo do Amazon DynamoDB para sua tabela.

    STREAMARN=$(aws dynamodb describe-table \
        --table-name Migration \
        --query "Table.LatestStreamArn" \
        --output text)
    
  10. Anexe a função Lambda à tabela do Amazon DynamoDB.

    aws lambda create-event-source-mapping --event-source $STREAMARN \
        --function-name dynamodb-spanner-lambda --enabled \
        --starting-position TRIM_HORIZON
    
  11. Para otimizar a capacidade de resposta durante o teste, adicione --batch-size 1 ao final do comando anterior, que aciona a função toda vez que você criar, atualizar ou excluir um item.

    A seguinte resposta é exibida:

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

Exportar a tabela do Amazon DynamoDB para o Amazon S3

  1. No Cloud Shell, crie uma variável para um nome de um intervalo que você vai usar em várias das seções a seguir.

    BUCKET=$DEVSHELL_PROJECT_ID-dynamodb-spanner-export
    
  2. Crie um intervalo do Amazon S3 para receber a exportação do DynamoDB.

    aws s3 mb s3://$BUCKET
    
  3. No Console de Gerenciamento da AWS, clique em Data Pipeline.

  4. Clique em Create new pipeline para definir o job de exportação.

  5. No campo Name, insira Export to Amazon S3.

  6. Para Source, selecione o seguinte:

    • Build using a template.
    • Export DynamoDB table to Amazon S3.
  7. Na seção Parameters, defina o seguinte:

    1. No campo Source DynamoDB table name, insira Migration.
    2. No campo Output S3 folder, clique no ícone da Pasta e selecione o intervalo do Amazon S3 [Your-Project-ID]-dynamodb-spanner-export que você acabou de criar, em que [YOUR-PROJECT-ID] representa seu ID do projeto do GCP.
    3. Para consumir toda a capacidade de leitura disponível durante a exportação, no campo DynamoDB read throughput ratio, digite 1. Em um ambiente de produção, você ajusta esse valor para não atrapalhar as operações ativas.
    4. No campo Region of your DynamoDB table, insira o nome da região, por exemplo, us-west-2.
  8. Para iniciar os jobs de backup imediatamente, na seção Schedule para Run, clique em On pipeline activation.

  9. Em Pipeline Configuration, no campo Logging, insira Disabled. Se você estiver seguindo este guia para migrar uma tabela de produção, deixe essa opção ativada e aponte para um intervalo separado do Amazon S3 para registros para ajudá-lo a solucionar erros. Deixe outros parâmetros com as configurações padrão.

  10. Para iniciar o processo de backup, clique em Activate.

  11. Se você receber uma solicitação para conferir os avisos de validação, clique em Activate. Em uma situação de produção, você define uma duração máxima para o job e ativa a geração de registros.

  12. Clique em Refresh para atualizar o status do processo de backup. O job leva vários minutos para criar os recursos e concluir a exportação. Em um ambiente de produção, é possível acelerar esse processo modificando os jobs do Pipeline de dados para usar mais recursos de EMR.

    Quando o processo terminar, observe o intervalo de saída.

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

    O job de exportação é feito quando há um arquivo chamado _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
    

Como abrir o banco de dados

Se você pausou gravações no banco de dados antes de exportar, é hora de reativar as gravações no banco de dados. Agora que a entrega do Cloud Pub/Sub está em vigor, é possível enviar quaisquer alterações na tabela que ocorreram após a exportação.

Copiar a tabela exportada para o Cloud Storage

  1. No Cloud Shell, crie um intervalo do Cloud Storage para receber os arquivos exportados do Amazon S3.

    gsutil mb gs://$BUCKET
    
  2. Sincronize os arquivos do Amazon S3 com o Cloud Storage. O comando rsync funciona para a maioria das operações de cópia. Se os arquivos de exportação forem grandes (vários GB ou mais), use o serviço de transferência do Cloud Storage para gerenciar a transferência em segundo plano.

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

    A seguinte resposta é exibida:

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

Importar os dados em lotes

  1. Para gravar os dados dos arquivos exportados na tabela do Cloud Spanner, execute um job do Cloud Dataflow com um código de amostra do 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 assistir ao progresso do job de importação, no Console do GCP, acesse o Cloud Dataflow.

      ACESSAR o Cloud Dataflow

    2. Enquanto o job está em execução, é possível assistir ao gráfico de execução para examinar os registros. Clique no job que mostra o Status Em execução.

      Como executar o job de importação

  2. Clique em cada etapa para ver quantos elementos foram processados. A importação é concluída quando todas as etapas forem bem-sucedidas. O mesmo número de elementos criados em sua tabela do Amazon DynamoDB é processado em cada etapa.

    Estágios de sucesso do job de importação

  3. Verifique se o número de registros na tabela de destino do Cloud Spanner corresponde ao número de itens na tabela do 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"

    A seguinte resposta é exibida:

    $ 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. Crie uma amostra de entradas aleatórias em cada tabela para garantir que os dados sejam consistentes.

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

    A seguinte resposta é exibida:

    $ 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. Consulte a tabela do Amazon DynamoDB com o mesmo Username retornado da consulta do Cloud Spanner na etapa anterior. Por exemplo, aallen2538. Seu valor é específico para o banco de dados.

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

    Os valores dos outros campos devem corresponder aos valores da resposta do Cloud Spanner. A seguinte resposta é exibida:

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

Replicar novas alterações

Quando o job de importação em lote é concluído, você configura uma tarefa de fluxo contínuo para gravar atualizações contínuas da tabela de origem no Cloud Spanner. Você assina os eventos do Cloud Pub/Sub e os grava no Cloud Spanner.

A função Lambda que você criou está configurada para capturar alterações na tabela de origem do Amazon DynamoDB e publicá-las no Cloud Pub/Sub.

  1. Crie uma assinatura para o tópico do Cloud Pub/Sub para o qual o AWS Lambda envia eventos.

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

    A seguinte resposta é exibida:

    $ gcloud pubsub subscriptions create spanner-migration --topic spanner-migration
    Created subscription [projects/your-project/subscriptions/spanner-migration].
    
  2. Para transmitir as alterações que entram no Cloud Pub/Sub para escrever na tabela Cloud Spanner, execute o job do Cloud Dataflow no 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. Semelhante à etapa de carregamento em lote, para acompanhar o progresso do job, no Console do GCP, acesse o Cloud Dataflow.

      ACESSAR o Cloud Dataflow

    2. Clique no job que tem o Status Em execução.

      Job em execução

      O gráfico de processamento mostra uma resposta semelhante à anterior, mas cada item processado é contado na janela de status. O tempo de atraso do sistema é uma estimativa aproximada de quanto atraso esperar antes que as alterações apareçam na tabela do Cloud Spanner.

      Processos em execução devido ao tempo de atraso

O job do Cloud Dataflow que você executou na fase de carregamento em lote era um conjunto finito de entrada, também conhecido como um conjunto de dados limitado. Esse job do Cloud Dataflow usa o Cloud Pub/Sub como fonte de streaming e é considerado ilimitado. Para ver mais informações sobre esses dois tipos de fontes, consulte a seção sobre PCollections no guia de programação do Apache Beam. O job do Cloud Dataflow nesta etapa deve permanecer ativo, portanto, não é encerrado quando termina. O job do Cloud Dataflow de streaming permanece no status Em execução, em vez do status Bem-sucedido.

Verificar a replicação

Faça algumas alterações na tabela de origem para verificar se as alterações são replicadas na tabela do Cloud Spanner.

  1. Consulte uma linha inexistente no Cloud Spanner.

    gcloud spanner databases execute-sql migrationdb \
        --instance=spanner-migration --sql=\
        "SELECT * FROM Migration WHERE Username='my-test-username'"
    
  2. Crie um registro no Amazon DynamoDB com a mesma chave que você usou na consulta do Cloud Spanner. Se o comando for executado com sucesso, não haverá resposta.

    aws dynamodb put-item \
        --table-name Migration \
        --item '{"Username" : {"S" : "my-test-username"}, "Subscribed" : {"BOOL" : false}}'
    
  3. Execute a consulta original novamente para verificar se a linha está no Cloud Spanner.

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

    A resposta mostra a linha inserida:

    $ 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. Altere alguns atributos no item original e atualize a tabela do 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
    

    A resposta aparece da seguinte maneira:

    $ 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. Verifique se as alterações são propagadas para a tabela do Cloud Spanner.

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

    A resposta aparece da seguinte maneira:

    $ 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. Exclua o item de teste da tabela de origem do Amazon DynamoDB.

    aws dynamodb delete-item \
        --table-name Migration \
        --key '{"Username": {"S":"my-test-username"}}'
    
  7. Verifique se a linha correspondente foi excluída da tabela do Cloud Spanner. Quando a mudança é propagada, o comando a seguir não retorna nenhuma linha:

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

Como usar tabelas intercaladas

O Cloud Spanner oferece suporte ao conceito de tabelas intercaladas. Esse é um modelo de concepção em que um item de nível superior tem vários itens aninhados relacionados a esse item de nível superior, como um cliente e seus pedidos, ou um jogador e suas pontuações no jogo. Se sua tabela de origem do Amazon DynamoDB usa uma chave primária composta de uma chave de hash e uma chave de intervalo, é possível modelar um esquema de tabela intercalada, conforme mostrado no diagrama a seguir. Essa estrutura permite consultar com eficiência a tabela intercalada ao unir campos na tabela pai.

Tabela de usuários comparada à tabela de pedidos

Aplicar índices secundários

É uma prática recomendada aplicar índices secundários às tabelas do Cloud Spanner depois de carregar os dados. Agora que a replicação está funcionando, você configura um índice secundário para acelerar as consultas. Como as tabelas do Cloud Spanner, os índices secundários do Cloud Spanner são totalmente consistentes. Eles não têm consistência eventual, o que é comum em muitos bancos de dados NoSQL. Esse recurso pode ajudar a simplificar a concepção do aplicativo.

Execute uma consulta que não use nenhum índice. Você está procurando as N principais ocorrências, considerando um determinado valor de coluna. Essa é uma consulta comum no Amazon DynamoDB para eficiência do banco de dados.

  1. Acesse o Cloud Spanner.

    ACESSAR o Cloud Spanner

  2. Clique em CONSULTA.

    Botão Consulta

  3. No campo Consulta, insira a consulta a seguir e clique em Executar consulta.

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

    Depois que a consulta for executada, clique em Explicação e anote as linhas verificadas em relação às linhas retornadas. Sem um índice, o Cloud Spanner verifica a tabela inteira para retornar um pequeno subconjunto de dados que corresponde à consulta.

    Linhas verificadas em comparação com as linhas retornadas

  4. Se isso representar uma consulta comum, crie um índice composto nas colunas Subscribed e ReminderDate. No console do Cloud Spanner, clique em Criar índice.

  5. Clique para ativar Editar como texto.

  6. Nas instruções DDL, insira a definição do índice.

    CREATE INDEX SubscribedDate
    ON Migration (
      Subscribed,
      ReminderDate
    )
    
  7. Para começar a construir o banco de dados em segundo plano, clique em Criar.

    Atualização do esquema em andamento

  8. Depois que o índice for criado, execute a consulta novamente e adicione o índice.

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

    Examine a explicação da consulta novamente. Observe que o número de linhas verificadas diminuiu. As linhas retornadas em cada etapa correspondem ao número retornado pela consulta.

    Explicação da consulta

Índices intercalados

Você pode configurar índices intercalados no Cloud Spanner. Os índices secundários discutidos na seção anterior estão na raiz da hierarquia do banco de dados e usam índices da mesma maneira que um banco de dados convencional. Um índice intercalado está dentro do contexto de sua linha intercalada. Consulte opções de índice para ver mais detalhes sobre onde aplicar índices intercalados.

Como ajustar ao modelo de dados

Para adaptar a parte de migração deste tutorial à sua própria situação, modifique os arquivos de origem do Apache Beam. É importante que você não altere o esquema de origem durante a janela de migração real, caso contrário, poderá perder dados.

  1. Para analisar o JSON recebido e criar mutações, use o GSON. Ajuste a definição JSON para corresponder aos seus dados.

    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. Ajuste o mapeamento JSON correspondente.

    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));
    });

Nas etapas anteriores, você modificou o código-fonte do Apache Beam para importação em massa. Modifique o código-fonte da parte de streaming do pipeline de maneira semelhante. Por fim, ajuste os scripts, os esquemas e os índices de criação de tabela do banco de dados de destino do Cloud Spanner.

Como fazer a limpeza

Para evitar que os recursos usados neste tutorial sejam cobrados na conta do Google Cloud Platform, faça o seguinte:

Excluir o projeto

  1. No Console do GCP, acesse a página "Projetos".

    Acessar a página Projetos

  2. Na lista de projetos, selecione um e clique em Excluir projeto.
  3. Na caixa de diálogo, digite o código do projeto e clique em Encerrar para excluí-lo.

Excluir recursos da AWS

Se sua conta da AWS for usada fora deste tutorial, tenha cuidado ao excluir os seguintes recursos:

  1. Exclua a tabela do DynamoDB chamada Migration.
  2. Exclua o intervalo do Amazon S3 e a função Lambda que você criou durante as etapas de migração.
  3. Por fim, exclua o usuário do AWS IAM criado durante este tutorial.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…