Transferir entre buckets do Cloud Storage

O Serviço de transferência do Cloud Storage pode ser usado para transferir grandes quantidades de dados entre buckets do Cloud Storage, dentro do mesmo projeto do Google Cloud ou entre projetos diferentes.

As migrações de bucket são úteis em vários cenários. Elas podem ser usadas para consolidar dados de projetos separados, transferir dados para um local de backup ou mudar o local dos dados.

Quando usar o Serviço de transferência do Cloud Storage

O Google Cloud oferece várias opções para transferir dados entre os buckets do Cloud Storage. Recomendamos as seguintes diretrizes:

  • Transferir menos de 1 TB: use gcloud. Confira mais instruções em Mover e renomear buckets.

  • Transferir mais de 1 TB: use o Serviço de transferência do Cloud Storage. O Serviço de transferência do Cloud Storage é uma opção de transferência gerenciada que fornece segurança, confiabilidade e desempenho prontos para uso. Isso elimina a necessidade de otimizar e manter scripts e de lidar com novas tentativas.

Neste guia, você vai ver as práticas recomendadas ao transferir dados entre buckets do Cloud Storage usando o Serviço de transferência do Cloud Storage.

Definir uma estratégia de transferência

A estratégia de transferência depende da complexidade da sua situação. Inclua as seguintes considerações em seu plano.

Escolher um nome de bucket

Para mover os dados para um bucket de armazenamento com um local diferente, escolha uma das seguintes abordagens:

  • Novo nome do bucket. Atualize os aplicativos para que apontem para um bucket de armazenamento com um nome diferente.
  • Mantenha o nome do bucket. Substitua o bucket de armazenamento para manter o nome atual e não precise atualizar os aplicativos.

Em ambos os casos, é preciso se planejar para inatividade e avisar os usuários de maneira adequada que essa inatividade está chegando. Analise as explicações a seguir para entender qual é a melhor escolha para você.

Novo nome do bucket

Com um novo nome de bucket, é necessário atualizar todo o código e os serviços que usam seu bucket atual. A maneira de fazer isso depende de como os aplicativos são criados e implantados.

Em determinadas configurações, essa abordagem pode ter menos inatividade, mas exige mais trabalho para garantir uma transição tranquila. Isso envolve as seguintes etapas:

  1. Copie os dados para um novo bucket de armazenamento.
  2. Como iniciar o tempo de inatividade.
  3. Atualizar os aplicativos para apontar para o novo bucket.
  4. Verificar se tudo funciona conforme o esperado e se todos os sistemas e contas relevantes têm acesso ao bucket.
  5. Excluir o bucket original.
  6. Como encerrar seu tempo de inatividade

Manter nome do bucket

Use essa abordagem se você preferir não mudar o código para apontar para um novo nome de bucket. Isso envolve as seguintes etapas:

  1. Copie os dados para um bucket de armazenamento temporário.
  2. Como iniciar o tempo de inatividade.
  3. Excluindo o bucket original.
  4. Criar um novo bucket com o mesmo nome do seu bucket original.
  5. Copiar os dados do bucket temporário para o novo.
  6. Excluir o bucket temporário.
  7. Verificar se tudo funciona conforme o esperado e se todos os sistemas e contas relevantes têm acesso ao bucket.
  8. Como encerrar seu tempo de inatividade

Menos tempo de inatividade

O Serviço de transferência do Cloud Storage não bloqueia leituras ou gravações nos buckets de origem ou de destino durante uma transferência.

Se você optar por bloquear manualmente leituras/gravações no seu bucket, poderá minimizar o tempo de inatividade transferindo seus dados em duas etapas: semente e sincronização.

  1. Transferência de origem: execute uma transferência em massa sem bloquear a leitura/gravação na origem.

  2. Transferência de sincronização: quando a primeira execução for concluída, bloqueie a leitura/gravação no bucket de origem e execute outra transferência. As transferências do Serviço de transferência do Cloud Storage são incrementais por padrão. Portanto, essa segunda transferência só vai transferir dados que foram alterados durante a transferência de origem.

Otimizar a velocidade da transferência

Ao estimar quanto tempo um job de transferência leva, considere os possíveis gargalos. Por exemplo, se a origem tiver bilhões de arquivos pequenos, a velocidade de transferência será limitada por QPS. Se os tamanhos de objetos forem grandes, a largura de banda pode ser o gargalo.

Os limites de largura de banda são definidos no nível da região e alocados de maneira justa em todos os projetos. Se houver largura de banda suficiente disponível, o Serviço de transferência do Cloud Storage concluirá cerca de 1.000 tarefas por job de transferência por segundo. Nesse caso, é possível acelerar uma transferência dividindo o job em vários jobs de transferência pequenos. Por exemplo, usando prefixos de inclusão e exclusão para transferir determinados arquivos.

Nos casos em que o local, a classe de armazenamento e a chave de criptografia são iguais, o Serviço de transferência do Cloud Storage não cria uma nova cópia dos bytes. Em vez disso, ele cria uma nova entrada de metadados que aponta para o blob de origem. Como resultado, o mesmo local e cópias de classe de um corpus grande são concluídas muito rapidamente e são apenas limitadas por QPS.

As exclusões também são operações somente de metadados. Para essas transferências, o carregamento em paralelo da transferência ao dividir em vários jobs pequenos aumentará a velocidade.

Preservar metadados

Os metadados de objeto a seguir são preservados ao fazer a transferência de dados entre buckets do Cloud Storage com o Serviço de transferência do Cloud Storage:

  • Metadados personalizados criados pelo usuário.
  • Campos de metadados de chave fixa do Cloud Storage, como Cache-Control, Content-Disposition, Content-Type e Custom-Time.
  • Tamanho do objeto.
  • Número de geração é preservado como um campo de metadados personalizado com a chave x-goog-reserved-source-generation, que você pode editar mais tarde ou remover.

Os seguintes campos de metadados podem ser preservados ao transferir usando a API:

  • ACLs (acl)
  • Classe de armazenamento (storageClass)
  • CMEK (kmsKey)
  • Retenção temporária (temporaryHold)
  • Horário de criação do objeto (customTime)

Consulte a referência da API TransferSpec para mais detalhes.

Os seguintes campos de metadados não são preservados:

  • Horário da última atualização (updated)
  • etag
  • componentCount

Se preservado, o horário de criação do objeto é armazenado como um campo personalizado, customTime. O tempo updated do objeto é redefinido após a transferência. Portanto, o tempo gasto pelo objeto na classe de armazenamento também é redefinido. Isso significa que um objeto no Coldline Storage, pós-transferência, precisa existir novamente por 90 dias no destino para evitar cobranças de exclusão antecipada.

É possível aplicar as políticas de ciclo de vida baseadas em createTime usando customTime. Os valores customTime existentes são substituídos.

Para mais detalhes sobre o que é preservado ou não, consulte Preservação dos metadados.

Processar objetos com controle de versão

Se você quiser transferir todas as versões dos seus objetos de armazenamento, e não apenas a mais recente, use a CLI gcloud ou a API REST para transferir seus dados, combinados com o recurso de manifesto do Serviço de transferência do Cloud Storage.

Para transferir todas as versões de objetos, faça o seguinte:

  1. Liste os objetos do bucket e copie-os em um arquivo JSON:

    gcloud storage ls --all-versions --recursive --json [SOURCE_BUCKET] > object-listing.json
    

    Esse comando normalmente lista cerca de mil objetos por segundo.

  2. Divida o arquivo JSON em dois arquivos CSV: um com versões não atuais e outro com as ativas:

    jq -r '.[] | select( .type=="cloud_object" and (.metadata | has("timeDeleted") | not)) | [.metadata.name, .metadata.generation] | @csv' object-listing.json > live-object-manifest.csv
    jq -r '.[] | select( .type=="cloud_object" and (.metadata | has("timeDeleted"))) | [.metadata.name, .metadata.generation] | @csv' object-listing.json > non-current-object-manifest.csv
    
  3. Ative o controle de versões do objeto no bucket de destino.

  4. Transfira as versões não atuais primeiro transmitindo o arquivo de manifesto non-current-object-manifest.csv como o valor do campo transferManifest.

  5. Em seguida, transfira as versões ativas da mesma maneira, especificando live-object-manifest.csv como o arquivo de manifesto.

Configurar opções de transferência

Estas são algumas das opções disponíveis ao configurar a transferência:

  • Geração de registros: o Cloud Logging fornece registros detalhados de objetos individuais, permitindo verificar o status da transferência e realizar outras verificações de integridade dos dados.

  • Filtragem: é possível usar prefixos de inclusão e exclusão para limitar em quais objetos o Serviço de transferência do Cloud Storage opera. Essa opção pode ser usada para dividir uma transferência em vários jobs de transferência para que eles possam ser executados em paralelo. Consulte Otimizar a velocidade de transferência para mais informações.

  • Opções de transferência: configure sua transferência para substituir itens existentes no bucket de destino, para excluir objetos no destino que não existem no conjunto de transferências ou excluir objetos transferidos da origem.

Transferir seus dados

Depois de definir sua estratégia de transferência, é possível realizar a transferência em si.

Criar um novo bucket

Antes de iniciar a transferência, crie um bucket de armazenamento. Para ajuda sobre como escolher um local de bucket apropriado, consulte location_considerations.

É recomendável copiar alguns dos metadados do bucket ao criar o novo bucket. Consulte Receber os metadados do bucket para saber como exibir os metadados do bucket de origem para que seja possível aplicar as mesmas configurações ao novo bucket.

Copiar objetos para o novo bucket

É possível copiar objetos do bucket de origem para um novo bucket usando o console do Google Cloud, a CLI gcloud, a API REST ou bibliotecas de cliente. A abordagem que você escolher depende da sua estratégia de transferência.

As instruções a seguir destinam-se ao caso de uso básico de transferência de objetos de um bucket para outro e precisam ser modificadas de acordo com suas necessidades.

Não inclua informações sensíveis, como informações de identificação pessoal (PII, na sigla em inglês) ou dados de segurança no nome do job de transferência. Os nomes dos recursos podem ser propagados para os nomes de outros recursos do Google Cloud e podem ser expostos aos sistemas internos do Google fora do seu projeto.

Console do Google Cloud

Use o Serviço de transferência do Cloud Storage no Console do Google Cloud:

  1. Abra a página "Transferir" no Console do Google Cloud.

    Abra a página Transferir

  2. Clique em Criar job de transferência.
  3. Siga as instruções detalhadas e clique em Próxima etapa ao concluir cada etapa:

    • Primeiras etapas: use o Google Cloud Storage como Tipo de origem e Tipo de destino.

    • Escolha uma origem: insira diretamente o nome do bucket pretendido ou clique em Procurar para localizar e selecionar o bucket desejado.

    • Escolha um destino: insira diretamente o nome do bucket pretendido ou clique em Procurar para localizar e selecionar o bucket desejado.

    • Escolha as configurações: selecione a opção Excluir arquivos da origem após a transferência.

    • Opções de programação: ignore esta seção.

  4. Depois de concluir as instruções, clique em Criar.

    Isso inicia o processo de cópia dos objetos do bucket antigo para o novo. Esse processo pode levar algum tempo. No entanto, depois de clicar em Criar, será possível sair do Console do Google Cloud.

    Para ver o andamento da transferência:

    Abra a página "Transferir" no Console do Google Cloud.

    Abra a página Transferir

    Para saber como conseguir informações detalhadas de erro sobre as operações com falha do Serviço de transferência do Cloud Storage no console do Google Cloud, consulte a Solução de problemas.

  5. Após a conclusão da transferência, não será necessário fazer nada para excluir os objetos do bucket antigo se a caixa de seleção Excluir objetos de origem após a conclusão da transferência estiver selecionada durante a configuração. No entanto, você também pode excluir o bucket antigo, o que precisa ser feito separadamente.

CLI da gcloud

Instalar a CLI gcloud

Se ainda não o fez, instale a ferramenta de linha de comando gcloud.

Em seguida, chame gcloud init para inicializar a ferramenta e especificar o ID do projeto e a conta do usuário. Consulte Como inicializar o SDK do Cloud para mais detalhes.

gcloud init

Adicionar a conta de serviço à pasta de destino

É necessário adicionar a conta de serviço do Serviço de transferência do Cloud Storage ao bucket de destino antes de criar uma transferência. Para fazer isso, use gcloud storage buckets add-iam-policy-binding:

gcloud storage buckets add-iam-policy-binding gs://bucket_name \
--member=serviceAccount:project-12345678@storage-transfer-service.iam.gserviceaccount.com \
--role=roles/storage.admin

Para ver instruções sobre como usar o Console do Google Cloud ou a API, consulte Usar permissões do IAM na documentação do Cloud Storage.

Criar o job de transferência

Para criar um novo job de transferência, use o comando gcloud transfer jobs create. A criação de um novo job inicia a transferência especificada, a menos que uma programação ou --do-not-run seja especificado.

gcloud transfer jobs create SOURCE DESTINATION

Em que:

  • SOURCE é a fonte de dados dessa transferência no formato gs://BUCKET_NAME.

  • DESTINATION é o novo bucket no formato gs://BUCKET_NAME.

As opções adicionais incluem:

  • Informações do job: é possível especificar --name e --description.

  • Programação: especifique --schedule-starts, --schedule-repeats-every e --schedule-repeats-until ou --do-not-run.

  • Condições de objeto: use condições para determinar quais objetos são transferidos. Elas incluem --include-prefixes e --exclude-prefixes, além das condições baseadas em tempo em --include-modified-[before | after]-[absolute | relative].

  • Opções de transferência: especifique se você quer substituir os arquivos de destino (--overwrite-when=different ou always) e se quer excluir determinados arquivos durante ou após a transferência (--delete-from=destination-if-unique ou source-after-transfer). Especifique também quais [valores de metadados preservar]metadados. Opcionalmente, defina uma classe de armazenamento em objetos transferidos (--custom-storage-class).

  • Notificações: configure as notificações de Pub/Sub para transferências com --notification-pubsub-topic, --notification-event-types e --notification-payload-format.

Para ver todas as opções, execute gcloud transfer jobs create --help.

Por exemplo, para transferir todos os objetos com o prefixo folder1:

gcloud transfer jobs create gs://old-bucket gs://new-bucket \
  --include-prefixes="folder1/"

REST

Neste exemplo, você aprenderá a mover arquivos de um bucket do Cloud Storage para outro. Por exemplo, é possível migrar dados para um bucket em outro local.

Solicitação usando transferJobs create:

POST https://storagetransfer.googleapis.com/v1/transferJobs
{
  "description": "YOUR DESCRIPTION",
  "status": "ENABLED",
  "projectId": "PROJECT_ID",
  "schedule": {
      "scheduleStartDate": {
          "day": 1,
          "month": 1,
          "year": 2025
      },
      "startTimeOfDay": {
          "hours": 1,
          "minutes": 1
      },
      "scheduleEndDate": {
          "day": 1,
          "month": 1,
          "year": 2025
      }
  },
  "transferSpec": {
      "gcsDataSource": {
          "bucketName": "GCS_SOURCE_NAME"
      },
      "gcsDataSink": {
          "bucketName": "GCS_SINK_NAME"
      },
      "transferOptions": {
          "deleteObjectsFromSourceAfterTransfer": true
      }
  }
}

Resposta:

200 OK
{
  "transferJob": [
      {
          "creationTime": "2015-01-01T01:01:00.000000000Z",
          "description": "YOUR DESCRIPTION",
          "name": "transferJobs/JOB_ID",
          "status": "ENABLED",
          "lastModificationTime": "2015-01-01T01:01:00.000000000Z",
          "projectId": "PROJECT_ID",
          "schedule": {
              "scheduleStartDate": {
                  "day": 1,
                  "month": 1,
                  "year": 2015
              },
              "startTimeOfDay": {
                  "hours": 1,
                  "minutes": 1
              }
          },
          "transferSpec": {
              "gcsDataSource": {
                  "bucketName": "GCS_SOURCE_NAME",
              },
              "gcsDataSink": {
                  "bucketName": "GCS_NEARLINE_SINK_NAME"
              },
              "objectConditions": {
                  "minTimeElapsedSinceLastModification": "2592000.000s"
              },
              "transferOptions": {
                  "deleteObjectsFromSourceAfterTransfer": true
              }
          }
      }
  ]
}

Bibliotecas de cliente

Neste exemplo, você aprenderá a mover arquivos de um bucket do Cloud Storage para outro. Por exemplo, você pode replicar dados para um bucket em outro local.

Para mais informações sobre as bibliotecas de cliente do Serviço de transferência do Cloud Storage, consulte Primeiros passos com as bibliotecas de cliente do Serviço de transferência do Cloud Storage.

Java

Procurando amostras mais antigas? Consulte o Guia de migração do serviço de transferência do Cloud Storage.

import com.google.protobuf.Duration;
import com.google.storagetransfer.v1.proto.StorageTransferServiceClient;
import com.google.storagetransfer.v1.proto.TransferProto.CreateTransferJobRequest;
import com.google.storagetransfer.v1.proto.TransferTypes.GcsData;
import com.google.storagetransfer.v1.proto.TransferTypes.ObjectConditions;
import com.google.storagetransfer.v1.proto.TransferTypes.Schedule;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferJob;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferJob.Status;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferOptions;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferSpec;
import com.google.type.Date;
import com.google.type.TimeOfDay;
import java.io.IOException;
import java.util.Calendar;

public class TransferToNearline {
  /**
   * Creates a one-off transfer job that transfers objects in a standard GCS bucket that are more
   * than 30 days old to a Nearline GCS bucket.
   */
  public static void transferToNearline(
      String projectId,
      String jobDescription,
      String gcsSourceBucket,
      String gcsNearlineSinkBucket,
      long startDateTime)
      throws IOException {

    // Your Google Cloud Project ID
    // String projectId = "your-project-id";

    // A short description of this job
    // String jobDescription = "Sample transfer job of old objects to a Nearline GCS bucket.";

    // The name of the source GCS bucket to transfer data from
    // String gcsSourceBucket = "your-gcs-source-bucket";

    // The name of the Nearline GCS bucket to transfer old objects to
    // String gcsSinkBucket = "your-nearline-gcs-bucket";

    // What day and time in UTC to start the transfer, expressed as an epoch date timestamp.
    // If this is in the past relative to when the job is created, it will run the next day.
    // long startDateTime =
    //     new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2000-01-01 00:00:00").getTime();

    // Parse epoch timestamp into the model classes
    Calendar startCalendar = Calendar.getInstance();
    startCalendar.setTimeInMillis(startDateTime);
    // Note that this is a Date from the model class package, not a java.util.Date
    Date date =
        Date.newBuilder()
            .setYear(startCalendar.get(Calendar.YEAR))
            .setMonth(startCalendar.get(Calendar.MONTH) + 1)
            .setDay(startCalendar.get(Calendar.DAY_OF_MONTH))
            .build();
    TimeOfDay time =
        TimeOfDay.newBuilder()
            .setHours(startCalendar.get(Calendar.HOUR_OF_DAY))
            .setMinutes(startCalendar.get(Calendar.MINUTE))
            .setSeconds(startCalendar.get(Calendar.SECOND))
            .build();

    TransferJob transferJob =
        TransferJob.newBuilder()
            .setDescription(jobDescription)
            .setProjectId(projectId)
            .setTransferSpec(
                TransferSpec.newBuilder()
                    .setGcsDataSource(GcsData.newBuilder().setBucketName(gcsSourceBucket))
                    .setGcsDataSink(GcsData.newBuilder().setBucketName(gcsNearlineSinkBucket))
                    .setObjectConditions(
                        ObjectConditions.newBuilder()
                            .setMinTimeElapsedSinceLastModification(
                                Duration.newBuilder().setSeconds(2592000 /* 30 days */)))
                    .setTransferOptions(
                        TransferOptions.newBuilder().setDeleteObjectsFromSourceAfterTransfer(true)))
            .setSchedule(Schedule.newBuilder().setScheduleStartDate(date).setStartTimeOfDay(time))
            .setStatus(Status.ENABLED)
            .build();

    // Create a Transfer Service client
    StorageTransferServiceClient storageTransfer = StorageTransferServiceClient.create();

    // Create the transfer job
    TransferJob response =
        storageTransfer.createTransferJob(
            CreateTransferJobRequest.newBuilder().setTransferJob(transferJob).build());

    System.out.println("Created transfer job from standard bucket to Nearline bucket:");
    System.out.println(response.toString());
  }
}

Python

Procurando amostras mais antigas? Consulte o Guia de migração do serviço de transferência do Cloud Storage.

from datetime import datetime

from google.cloud import storage_transfer
from google.protobuf.duration_pb2 import Duration


def create_daily_nearline_30_day_migration(
    project_id: str,
    description: str,
    source_bucket: str,
    sink_bucket: str,
    start_date: datetime,
):
    """Create a daily migration from a GCS bucket to a Nearline GCS bucket
    for objects untouched for 30 days."""

    client = storage_transfer.StorageTransferServiceClient()

    # The ID of the Google Cloud Platform Project that owns the job
    # project_id = 'my-project-id'

    # A useful description for your transfer job
    # description = 'My transfer job'

    # Google Cloud Storage source bucket name
    # source_bucket = 'my-gcs-source-bucket'

    # Google Cloud Storage destination bucket name
    # sink_bucket = 'my-gcs-destination-bucket'

    transfer_job_request = storage_transfer.CreateTransferJobRequest(
        {
            "transfer_job": {
                "project_id": project_id,
                "description": description,
                "status": storage_transfer.TransferJob.Status.ENABLED,
                "schedule": {
                    "schedule_start_date": {
                        "day": start_date.day,
                        "month": start_date.month,
                        "year": start_date.year,
                    }
                },
                "transfer_spec": {
                    "gcs_data_source": {
                        "bucket_name": source_bucket,
                    },
                    "gcs_data_sink": {
                        "bucket_name": sink_bucket,
                    },
                    "object_conditions": {
                        "min_time_elapsed_since_last_modification": Duration(
                            seconds=2592000  # 30 days
                        )
                    },
                    "transfer_options": {
                        "delete_objects_from_source_after_transfer": True
                    },
                },
            }
        }
    )

    result = client.create_transfer_job(transfer_job_request)
    print(f"Created transferJob: {result.name}")

Verificar objetos copiados

Após a conclusão da transferência, recomendamos que você realize outras verificações de integridade de dados.

  • Valide se os objetos foram copiados corretamente verificando os metadados nos objetos, como somas de verificação e tamanho.

  • Verifique se a versão correta dos objetos foi copiada. O Serviço de transferência do Cloud Storage oferece uma opção pronta para verificar se os objetos são cópias. Se você ativou geração de registros , ver registros para verificar se todos os objetos foram copiados, incluindo os campos de metadados correspondentes.

Começar a usar o bucket de destino

Quando a migração for concluída e verificada, atualize todos os aplicativos ou cargas de trabalho para que eles usem o nome do bucket de destino. Verifique os registros de acesso a dados em Registros de auditoria do Cloud para garantir que as operações modifiquem e leiam os objetos corretamente.

Excluir o bucket original

Quando tudo estiver funcionando bem, exclua o bucket original.

O Serviço de transferência do Cloud Storage oferece a opção de excluir objetos depois de eles serem transferidos. Basta especificar deleteObjectsFromSourceAfterTransfer: true na configuração do job ou selecionar a opção no Console do Google Cloud.

Programar exclusão de objeto

Para programar a exclusão dos objetos posteriormente, use uma combinação de um job de transferência programada e a opção deleteObjectsUniqueInSink = true.

O job de transferência precisa ser configurado para transferir um bucket vazio para o bucket que contém os objetos. Isso faz com que o Serviço de transferência do Cloud Storage liste os objetos e comece a excluí-los. Como as exclusões são uma operação somente de metadados, o job de transferência é vinculado apenas a QPS. Para acelerar o processo, divida a transferência em vários jobs, cada um agindo em um conjunto distinto de prefixos.

Se preferir, o Google Cloud oferece um programador de cron job gerenciado. Para mais informações, consulte Programar job de transferência do STS do Google Cloud com o Cloud Scheduler.