Transfira dados entre sistemas de ficheiros

Esta página mostra-lhe como transferir dados entre dois sistemas de ficheiros POSIX. Os exemplos de utilização comuns incluem:

  • Transferência rápida para a nuvem e HPC híbrido: transfira rapidamente grandes conjuntos de dados de local para a nuvem para processamento.
  • Migração e sincronização para o Filestore: migre ou sincronize dados de um sistema de ficheiros no local para o Filestore.
  • Transferência de ficheiros gerida: transfira dados de forma segura e fiável entre centros de dados ou entre dois sistemas de ficheiros na nuvem.

Diretrizes de desempenho da transferência

As seguintes diretrizes podem ajudar a maximizar o desempenho durante as transferências do sistema de ficheiros para o sistema de ficheiros.

Implementação de agentes

Em geral, recomendamos que use três agentes em cada um dos conjuntos de agentes de origem e de destino. Monitorize a transferência e adicione mais agentes, se necessário. Cada agente precisa de 4 vCPU e 8 GiB de RAM.

Se estiver a migrar para uma instância do Filestore, o Filestore recomenda que use o tipo de instância n2-standard-8 para cada agente. Especifique nconnect=2 quando montar a instância numa VM do Compute Engine. Consulte as diretrizes de desempenho do Filestore para mais informações sobre como otimizar e testar o desempenho das instâncias.

Transferir um grande número de ficheiros pequenos

Para um melhor desempenho ao transferir um grande número de ficheiros pequenos, recomendamos que divida os ficheiros em vários diretórios e evite um único diretório com milhões de ficheiros.

Antes de começar

Antes de poder realizar as tarefas descritas nesta página, conclua os passos pré-requisitos.

Crie pools de agentes e instale agentes

Para transferências de sistema de ficheiros para sistema de ficheiros, tem de criar pools de agentes e agentes para os sistemas de ficheiros de origem e destino. Os agentes do conjunto de agentes de origem têm de ser instalados em máquinas ou VMs que tenham acesso ao sistema de ficheiros de origem. Os agentes do conjunto de agentes de destino têm de ser instalados em máquinas ou VMs que tenham acesso ao sistema de ficheiros de destino.

Não inclua informações confidenciais, como informações de identificação pessoal (IIP) ou dados de segurança, no prefixo do ID do agente ou no nome do conjunto de agentes. Os nomes dos recursos podem ser propagados para os nomes de outros Google Cloud recursos e podem ser expostos a sistemas internos da Google fora do seu projeto.

Crie um conjunto de agentes de origem

Crie um conjunto de agentes de origem através de um dos seguintes métodos:

CLI gcloud

Crie um conjunto de agentes de origem executando o seguinte comando:

gcloud transfer agent-pools create SOURCE_AGENT_POOL

Substitua SOURCE_AGENT_POOL pelo nome que quer dar ao conjunto de agentes de origem.

Google Cloud consola

  1. Na Google Cloud consola, aceda à página Pools de agentes.

    Aceda a Conjuntos de agentes

    É apresentada a página Conjuntos de agentes, que lista os conjuntos de agentes existentes.

  2. Clique em Criar outro conjunto.

  3. Introduza um nome para o conjunto.

  4. Clique em Criar.

Instale agentes para o conjunto de agentes de origem

Instale agentes para o conjunto de agentes de origem numa máquina ou numa VM que tenha acesso ao sistema de ficheiros de origem:

CLI gcloud

Instale agentes para o conjunto de agentes de origem executando o seguinte comando:

gcloud transfer agents install --pool=SOURCE_AGENT_POOL --count=NUMBER_OF_AGENTS \
  --mount-directories=MOUNT_DIRECTORIES

Substitua o seguinte:

  • SOURCE_AGENT_POOL com o nome do conjunto de agentes de origem.
  • NUMBER_OF_AGENTS com o número de agentes que quer instalar para o conjunto de agentes de origem. Para determinar o número ideal de agentes para o seu ambiente, consulte os requisitos e as práticas recomendadas para agentes.
  • MOUNT_DIRECTORIES com uma lista separada por vírgulas de diretórios no sistema de ficheiros de origem a partir dos quais copiar. Omitir esta flag monta todo o sistema de ficheiros, o que pode apresentar um risco de segurança.

Google Cloud consola

  1. Na Google Cloud consola, aceda à página Pools de agentes.

    Aceda a Conjuntos de agentes

    É apresentada a página Conjuntos de agentes, que lista os conjuntos de agentes existentes.

  2. Clique no nome do conjunto de agentes de origem que acabou de criar.

  3. No separador Agentes, clique em Instalar agente.

  4. Siga as instruções na Google Cloud consola para instalar o Docker e iniciar o agente.

Crie um grupo de agentes de destino e instale agentes

Repita os passos anteriores para criar um conjunto de agentes de destino e instalar agentes.

Crie um contentor do Cloud Storage como intermediário

As transferências de sistema de ficheiros para sistema de ficheiros requerem um contentor do Cloud Storage como intermediário para a transferência de dados.

  1. Crie um contentor da classe Standard do Cloud Storage com as seguintes definições:

    • Encriptação: pode especificar uma chave de encriptação gerida pelo cliente (CMEK). Caso contrário, é usado um Google-owned and Google-managed encryption key .
    • Controlo de versões de objetos, Bloqueio de contentores e retenções de objetos predefinidas: mantenha estas funcionalidades desativadas.
  2. Conceda autorizações e funções através de um dos seguintes métodos:

    • Conceda à conta de serviço do Serviço de transferência de armazenamento a função de administrador de armazenamento (roles/storage.admin) para o contentor.
    • Use gcloud transfer authorize para autorizar a sua conta para todas as funcionalidades do serviço de transferência de armazenamento. Este comando concede autorizações de administrador de armazenamento ao nível do projeto:

      gcloud transfer authorize --add-missing
      

Crie uma tarefa de transferência

CLI gcloud

Para criar uma transferência do sistema de ficheiros de origem para o sistema de ficheiros de destino, execute

gcloud transfer jobs create SOURCE_DIRECTORY DESTINATION_DIRECTORY \
    --source-agent-pool=SOURCE_AGENT_POOL \
    --destination-agent-pool=DESTINATION_AGENT_POOL \
    --intermediate-storage-path= gs://STORAGE_BUCKET/FOLDER/

Substitua as seguintes variáveis:

  • SOURCE_DIRECTORY com o caminho do diretório de origem.
  • DESTINATION_DIRECTORY com o caminho do diretório de destino.
  • SOURCE_AGENT_POOL com o nome do conjunto de agentes de origem.
  • DESTINATION_AGENT_POOL com o nome do conjunto de agentes de destino.
  • STORAGE_BUCKET com o nome do contentor do Cloud Storage.
  • FOLDER com o nome da pasta para a qual quer transferir os dados.

Quando inicia uma tarefa de transferência, o sistema calcula primeiro os dados na origem e no destino para determinar os dados de origem que são novos ou foram atualizados desde a transferência anterior. Apenas os novos dados são transferidos.

Bibliotecas cliente

Ir


import (
	"context"
	"fmt"
	"io"

	storagetransfer "cloud.google.com/go/storagetransfer/apiv1"
	"cloud.google.com/go/storagetransfer/apiv1/storagetransferpb"
)

func transferFromPosix(w io.Writer, projectID string, sourceAgentPoolName string, rootDirectory string, gcsSinkBucket string) (*storagetransferpb.TransferJob, error) {
	// Your project id
	// projectId := "myproject-id"

	// The agent pool associated with the POSIX data source. If not provided, defaults to the default agent
	// sourceAgentPoolName := "projects/my-project/agentPools/transfer_service_default"

	// The root directory path on the source filesystem
	// rootDirectory := "/directory/to/transfer/source"

	// The ID of the GCS bucket to transfer data to
	// gcsSinkBucket := "my-sink-bucket"

	ctx := context.Background()
	client, err := storagetransfer.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("storagetransfer.NewClient: %w", err)
	}
	defer client.Close()

	req := &storagetransferpb.CreateTransferJobRequest{
		TransferJob: &storagetransferpb.TransferJob{
			ProjectId: projectID,
			TransferSpec: &storagetransferpb.TransferSpec{
				SourceAgentPoolName: sourceAgentPoolName,
				DataSource: &storagetransferpb.TransferSpec_PosixDataSource{
					PosixDataSource: &storagetransferpb.PosixFilesystem{RootDirectory: rootDirectory},
				},
				DataSink: &storagetransferpb.TransferSpec_GcsDataSink{
					GcsDataSink: &storagetransferpb.GcsData{BucketName: gcsSinkBucket},
				},
			},
			Status: storagetransferpb.TransferJob_ENABLED,
		},
	}

	resp, err := client.CreateTransferJob(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("failed to create transfer job: %w", err)
	}
	if _, err = client.RunTransferJob(ctx, &storagetransferpb.RunTransferJobRequest{
		ProjectId: projectID,
		JobName:   resp.Name,
	}); err != nil {
		return nil, fmt.Errorf("failed to run transfer job: %w", err)
	}
	fmt.Fprintf(w, "Created and ran transfer job from %v to %v with name %v", rootDirectory, gcsSinkBucket, resp.Name)
	return resp, nil
}

Java

import com.google.storagetransfer.v1.proto.StorageTransferServiceClient;
import com.google.storagetransfer.v1.proto.TransferProto;
import com.google.storagetransfer.v1.proto.TransferTypes.GcsData;
import com.google.storagetransfer.v1.proto.TransferTypes.PosixFilesystem;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferJob;
import com.google.storagetransfer.v1.proto.TransferTypes.TransferSpec;
import java.io.IOException;

public class TransferBetweenPosix {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.

    // Your project id
    String projectId = "my-project-id";

    // The agent pool associated with the POSIX data source. If not provided, defaults to the
    // default agent
    String sourceAgentPoolName = "projects/my-project-id/agentPools/transfer_service_default";

    // The agent pool associated with the POSIX data sink. If not provided, defaults to the default
    // agent
    String sinkAgentPoolName = "projects/my-project-id/agentPools/transfer_service_default";

    // The root directory path on the source filesystem
    String rootDirectory = "/directory/to/transfer/source";

    // The root directory path on the sink filesystem
    String destinationDirectory = "/directory/to/transfer/sink";

    // The ID of the GCS bucket for intermediate storage
    String bucketName = "my-intermediate-bucket";

    transferBetweenPosix(
        projectId,
        sourceAgentPoolName,
        sinkAgentPoolName,
        rootDirectory,
        destinationDirectory,
        bucketName);
  }

  public static void transferBetweenPosix(
      String projectId,
      String sourceAgentPoolName,
      String sinkAgentPoolName,
      String rootDirectory,
      String destinationDirectory,
      String bucketName)
      throws IOException {

    TransferJob transferJob =
        TransferJob.newBuilder()
            .setProjectId(projectId)
            .setTransferSpec(
                TransferSpec.newBuilder()
                    .setSinkAgentPoolName(sinkAgentPoolName)
                    .setSourceAgentPoolName(sourceAgentPoolName)
                    .setPosixDataSource(
                        PosixFilesystem.newBuilder().setRootDirectory(rootDirectory).build())
                    .setPosixDataSink(
                        PosixFilesystem.newBuilder().setRootDirectory(destinationDirectory).build())
                    .setGcsIntermediateDataLocation(
                        GcsData.newBuilder().setBucketName(bucketName).build())
                    .build())
            .setStatus(TransferJob.Status.ENABLED)
            .build();

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources,
    // or use "try-with-close" statement to do this automatically.
    try (StorageTransferServiceClient storageTransfer = StorageTransferServiceClient.create()) {

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

      System.out.println(
          "Created and ran a transfer job from "
              + rootDirectory
              + " to "
              + destinationDirectory
              + " with name "
              + response.getName());
    }
  }
}

Node.js


// Imports the Google Cloud client library
const {
  StorageTransferServiceClient,
} = require('@google-cloud/storage-transfer');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// Your project id
// const projectId = 'my-project'

// The agent pool associated with the POSIX data source. Defaults to the default agent
// const sourceAgentPoolName = 'projects/my-project/agentPools/transfer_service_default'

// The agent pool associated with the POSIX data sink. Defaults to the default agent
// const sinkAgentPoolName = 'projects/my-project/agentPools/transfer_service_default'

// The root directory path on the source filesystem
// const rootDirectory = '/directory/to/transfer/source'

// The root directory path on the sink filesystem
// const destinationDirectory = '/directory/to/transfer/sink'

// The ID of the GCS bucket for intermediate storage
// const bucketName = 'my-intermediate-bucket'

// Creates a client
const client = new StorageTransferServiceClient();

/**
 * Creates a request to transfer from the local file system to the sink bucket
 */
async function transferDirectory() {
  const createRequest = {
    transferJob: {
      projectId,
      transferSpec: {
        sourceAgentPoolName,
        sinkAgentPoolName,
        posixDataSource: {
          rootDirectory,
        },
        posixDataSink: {
          rootDirectory: destinationDirectory,
        },
        gcsIntermediateDataLocation: {
          bucketName,
        },
      },
      status: 'ENABLED',
    },
  };

  // Runs the request and creates the job
  const [transferJob] = await client.createTransferJob(createRequest);

  const runRequest = {
    jobName: transferJob.name,
    projectId: projectId,
  };

  await client.runTransferJob(runRequest);

  console.log(
    `Created and ran a transfer job from '${rootDirectory}' to '${destinationDirectory}' with name ${transferJob.name}`
  );
}

transferDirectory();

Python

from google.cloud import storage_transfer


def transfer_between_posix(
    project_id: str,
    description: str,
    source_agent_pool_name: str,
    sink_agent_pool_name: str,
    root_directory: str,
    destination_directory: str,
    intermediate_bucket: str,
):
    """Creates a transfer between POSIX file systems."""

    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'

    # The agent pool associated with the POSIX data source.
    # Defaults to 'projects/{project_id}/agentPools/transfer_service_default'
    # source_agent_pool_name = 'projects/my-project/agentPools/my-agent'

    # The agent pool associated with the POSIX data sink.
    # Defaults to 'projects/{project_id}/agentPools/transfer_service_default'
    # sink_agent_pool_name = 'projects/my-project/agentPools/my-agent'

    # The root directory path on the source filesystem
    # root_directory = '/directory/to/transfer/source'

    # The root directory path on the destination filesystem
    # destination_directory = '/directory/to/transfer/sink'

    # The Google Cloud Storage bucket for intermediate storage
    # intermediate_bucket = 'my-intermediate-bucket'

    transfer_job_request = storage_transfer.CreateTransferJobRequest(
        {
            "transfer_job": {
                "project_id": project_id,
                "description": description,
                "status": storage_transfer.TransferJob.Status.ENABLED,
                "transfer_spec": {
                    "source_agent_pool_name": source_agent_pool_name,
                    "sink_agent_pool_name": sink_agent_pool_name,
                    "posix_data_source": {
                        "root_directory": root_directory,
                    },
                    "posix_data_sink": {
                        "root_directory": destination_directory,
                    },
                    "gcs_intermediate_data_location": {
                        "bucket_name": intermediate_bucket
                    },
                },
            }
        }
    )

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

Faça a gestão dos contentores intermediários

Após a conclusão de uma tarefa de transferência, o Serviço de transferência de armazenamento guarda os registos de transferência que indicam os dados transferidos e os dados cuja transferência falhou no contentor. Após a transferência, as tarefas de limpeza são iniciadas automaticamente para eliminar os dados intermédios. Em alguns casos, as tarefas de limpeza não conseguem eliminar todos os dados no contentor. Para eliminar dados que não são apagados durante a limpeza, siga as instruções abaixo para eliminar os dados manualmente ou definir uma regra do ciclo de vida para eliminar os dados automaticamente.

Limpeza manual

Elimine dados do contentor intermediário executando os seguintes comandos com base no tipo de dados que quer eliminar.

  • Para apagar os dados no contentor intermediário que não foram eliminados durante a limpeza, execute o seguinte comando:

    gcloud storage rm gs://STORAGE_BUCKET/PREFIX**
    
  • Para eliminar todos os dados, incluindo os registos de transferência, especifique a raiz do contentor usando o caráter universal (*) que corresponde a tudo.

    gcloud storage rm gs://STORAGE_BUCKET/*
    
  • Para eliminar o contentor, execute o seguinte comando:

    gcloud storage rm gs://STORAGE_BUCKET
    

Substitua as seguintes variáveis:

  • STORAGE_BUCKET com o nome do contentor intermediário.

  • PREFIX com o nome da pasta para a qual os dados foram transferidos no contentor intermediário.

Defina uma regra do ciclo de vida

Para eliminar dados que não são apagados pelo ciclo de limpeza automático, defina uma regra de ciclo de vida para o contentor do Cloud Storage. Use a condição age para apagar dados intermédios no contentor especificando um período superior à tarefa de transferência mais longa que usa o contentor como intermediário. Se a condição de idade especificada for inferior ao tempo necessário para transferir o ficheiro do contentor intermediário para o destino, a transferência de ficheiros falha.

Opcionalmente, use a condição matchesPrefix para apagar os dados na pasta especificada para o contentor intermédio. Para eliminar registos de transferência juntamente com os dados no contentor, a condição matchesPrefix não é necessária.

Preservar os metadados dos ficheiros

Para preservar os metadados dos ficheiros, incluindo UID, GID, MODE e links simbólicos numéricos:

CLI gcloud

Use o campo --preserve-metadata para especificar o comportamento de preservação desta transferência. As opções que se aplicam a transferências do sistema de ficheiros são: gid, mode, symlink e uid.

API REST

Especifique as opções adequadas num objeto metadataOptions.

Consulte o artigo Preservar atributos POSIX opcionais para mais informações.

Exemplo de transferência com a CLI gcloud

Neste exemplo, transferimos dados do diretório /tmp/datasource na VM1 para /tmp/destination na VM2.

  1. Configure a origem da transferência.

    1. Crie o grupo de agentes de origem:

      gcloud transfer agent-pools create source_agent_pool
      
    2. Na VM1, instale os agentes para source_agent_pool executando o seguinte comando:

      gcloud transfer agents install --pool=source_agent_pool \
          --count=1 \
          --mount-directories="/tmp/datasource"
      
  2. Configure o destino da transferência.

    1. Crie o grupo de agentes de destino:

      gcloud transfer agent-pools create destination_agent_pool
      
    2. Na VM2, instale os agentes para destination_agent_pool executando o seguinte comando:

      gcloud transfer agents install --pool=destination_agent_pool \
          --count=3 \
          --mount-directories="/tmp/destination"
      
  3. Crie um contentor do Cloud Storage intermediário.

    1. Crie um contentor com o nome my-intermediary-bucket:

      gcloud storage buckets create gs://my-intermediary-bucket
      
    2. Autorize a sua conta para todas as funcionalidades do serviço de transferência de armazenamento executando o seguinte comando:

      gcloud transfer authorize --add-missing
      
  4. Crie uma tarefa de transferência executando o seguinte comando:

    gcloud transfer jobs create posix:///tmp/datasource posix:///tmp/destination \
        --source-agent-pool=source_agent_pool \
        --destination-agent-pool=destination_agent_pool \
        --intermediate-storage-path=gs://my-intermediary-bucket
    

O que se segue?