Transférez des données entre systèmes de fichiers

Cette page vous explique comment transférer des données entre deux systèmes de fichiers POSIX. Vous trouverez ci-dessous des cas d'utilisation courants :

  • Utilisation intensive dans le cloud et HPC hybride : transférez rapidement des ensembles de données volumineux sur site vers le cloud en vue de leur traitement.
  • Migration et synchronisation avec Filestore : migrez ou synchronisez les données d'un système de fichiers sur site vers Filestore.
  • Transfert de fichiers géré : transférez des données de manière sécurisée et fiable entre des centres de données ou entre deux systèmes de fichiers dans le cloud.

Consignes concernant les performances des transferts

Les consignes suivantes peuvent vous aider à maximiser les performances lors des transferts de système de fichiers vers un autre système de fichiers.

Déploiement de l'agent

En général, nous vous recommandons d'utiliser trois agents dans chacun des pools d'agents source et de destination. Surveillez le transfert et ajoutez d'autres agents si nécessaire. Chaque agent a besoin de 4 vCPU et de 8 Gio de RAM.

Si vous effectuez une migration vers une instance Filestore, Filestore recommande d'utiliser le type d'instance n2-standard-8 pour chaque agent. Spécifiez nconnect=2 lorsque vous installez l'instance sur une VM Compute Engine. Pour en savoir plus sur l'optimisation et le test des performances des instances, consultez les consignes de performances de Filestore.

Transférer un grand nombre de petits fichiers

Pour de meilleures performances lors du transfert d'un grand nombre de petits fichiers, nous vous recommandons de les répartir dans plusieurs répertoires et d'éviter un seul répertoire contenant des millions de fichiers.

Avant de commencer

Avant de pouvoir effectuer les tâches décrites sur cette page, suivez les étapes préalables.

Créer des pools d'agents et installer des agents

Pour les transferts de système de fichiers à système de fichiers, vous devez créer des pools d'agents et des agents à la fois pour les systèmes de fichiers sources et de destination. Les agents pour le pool d'agents sources doivent être installés sur des machines ou des VM ayant accès au système de fichiers source. Les agents pour le pool d'agents de destination doivent être installés sur des machines ou des VM ayant accès au système de fichiers de destination.

N'incluez pas d'informations sensibles telles que des informations permettant d'identifier personnellement l'utilisateur ou des données de sécurité dans le préfixe de l'ID de l'agent ou le nom du pool d'agents. Les noms de ressources peuvent être propagés aux noms d'autres ressources Google Cloud et peuvent être exposés à des systèmes internes à Google en dehors de votre projet.

Créer un pool d'agents sources

Créez un pool d'agents sources à l'aide de l'une des méthodes suivantes :

CLI gcloud

Créez un pool d'agents sources en exécutant la commande suivante :

gcloud transfer agent-pools create SOURCE_AGENT_POOL

Remplacez SOURCE_AGENT_POOL par le nom que vous souhaitez attribuer au pool d'agents sources.

console Google Cloud

  1. Dans la console Google Cloud, accédez à la page Pools d'agents.

    Accéder aux pools d'agents

    La page Pools d'agents s'affiche. Elle répertorie vos pools d'agents existants.

  2. Cliquez sur Créer un autre pool.

  3. Attribuez un nom au pool.

  4. Cliquez sur Create (Créer).

Installer des agents pour le pool d'agents sources

Installez des agents pour le pool d'agents sources sur une machine ou une VM ayant accès au système de fichiers source :

CLI gcloud

Installez des agents pour le pool d'agents sources en exécutant la commande suivante :

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

Remplacez les éléments suivants :

  • SOURCE_AGENT_POOL par le nom du pool d'agents sources
  • NUMBER_OF_AGENTS par le nombre d'agents que vous souhaitez installer pour le pool d'agents sources Pour déterminer le nombre optimal d'agents pour votre environnement, consultez la section Conditions requises et bonnes pratiques pour les agents.
  • MOUNT_DIRECTORIES par une liste de répertoires du système de fichiers source à partir duquel effectuer la copie, séparés par des virgules. L'omission de cet indicateur monte l'ensemble du système de fichiers, ce qui peut présenter un risque de sécurité.

Console Google Cloud

  1. Dans la console Google Cloud, accédez à la page Pools d'agents.

    Accéder aux pools d'agents

    La page Pools d'agents s'affiche. Elle répertorie vos pools d'agents existants.

  2. Cliquez sur le nom du pool d'agents sources que vous venez de créer.

  3. Sous l'onglet Agents, cliquez sur Installer l'agent.

  4. Suivez les instructions de la console Google Cloud pour installer Docker et démarrer l'agent.

Créer un pool d'agents de destination et installer des agents

Répétez les étapes précédentes pour créer un pool d'agents de destination et installer des agents.

Créer un bucket Cloud Storage en tant qu'intermédiaire

Les transferts d'un système de fichiers vers un autre système de fichiers nécessitent un bucket Cloud Storage comme intermédiaire pour le transfert de données.

  1. Créez un bucket Cloud Storage de classe Standard avec les paramètres suivants :

    • Chiffrement : vous pouvez spécifier une clé de chiffrement gérée par le client (CMEK). Sinon, une clé appartenant à Google et gérée par Google est utilisée.
    • Gestion des versions d'objets, Verrou de bucket et Préservations d'objets par défaut : désactivez ces fonctionnalités.
  2. Accordez des autorisations et des rôles en utilisant l'une des méthodes suivantes :

    • Accordez au compte de service associé au service de transfert de stockage le rôle d'administrateur de l'espace de stockage (roles/storage.admin) pour le bucket.
    • Utilisez gcloud transfer authorize pour autoriser votre compte pour toutes les fonctionnalités du service de transfert de stockage. Cette commande accorde les autorisations d'administration de l'espace de stockage sur tout le projet :

      gcloud transfer authorize --add-missing
      

Créer un job de transfert

CLI gcloud

Pour créer un transfert du système de fichiers source vers le système de fichiers de destination, exécutez la commande suivante :

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/

Remplacez les variables suivantes :

  • SOURCE_DIRECTORY par le chemin du répertoire source
  • DESTINATION_DIRECTORY par le chemin du répertoire de destination
  • SOURCE_AGENT_POOL par le nom du pool d'agents sources
  • DESTINATION_AGENT_POOL par le nom du pool d'agents de destination
  • STORAGE_BUCKET par le nom du bucket Cloud Storage
  • FOLDER avec le nom du dossier dans lequel vous souhaitez transférer les données.

Lorsque vous démarrez une tâche de transfert, le système calcule d'abord les données dans la source et la destination pour déterminer les données sources nouvelles ou mises à jour depuis le transfert précédent. Seules les nouvelles données sont transférées.

Bibliothèques clientes

Go


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

Gérer les buckets intermédiaires

Une fois une tâche de transfert terminée, le service de transfert de stockage enregistre des journaux de transfert dans le bucket, qui indiquent les données transférées et celles qui n'ont pas pu l'être. Après le transfert, des tâches de nettoyage sont lancées automatiquement pour supprimer les données intermédiaires. Dans certains cas, les tâches de nettoyage ne parviennent pas à supprimer toutes les données du bucket. Pour supprimer les données qui ne sont pas effacées lors du nettoyage, suivez les instructions ci-dessous pour les supprimer manuellement ou pour définir une règle de cycle de vie afin de les supprimer automatiquement.

Nettoyage manuel

Supprimez les données du bucket intermédiaire en exécutant les commandes suivantes en fonction du type de données que vous souhaitez supprimer.

  • Pour effacer les données du bucket intermédiaire qui n'ont pas été supprimées lors du nettoyage, exécutez la commande suivante:

    gcloud storage rm gs://STORAGE_BUCKET/PREFIX**
    
  • Pour supprimer toutes les données, y compris les journaux de transfert, spécifiez la racine du bucket à l'aide du caractère générique tout correspond (*).

    gcloud storage rm gs://STORAGE_BUCKET/*
    
  • Pour supprimer le bucket, exécutez la commande suivante:

    gcloud storage rm gs://STORAGE_BUCKET
    

Remplacez les variables suivantes :

  • STORAGE_BUCKET par le nom du bucket intermédiaire.

  • PREFIX par le nom du dossier dans lequel les données ont été transférées dans le bucket intermédiaire.

Définir une règle de cycle de vie

Pour supprimer les données qui ne sont pas effacées par le cycle de nettoyage automatique, définissez une règle de cycle de vie pour le bucket Cloud Storage. Utilisez la condition age pour effacer les données intermédiaires du bucket en spécifiant une période plus longue que la tâche de transfert la plus longue qui utilise le bucket comme intermédiaire. Si la condition d'âge spécifiée est inférieure au temps requis pour télécharger le fichier du bucket intermédiaire vers la destination, le transfert de fichier échoue.

Vous pouvez également utiliser la condition matchesPrefix pour effacer les données du dossier que vous avez spécifié pour le bucket intermédiaire. Pour supprimer les journaux de transfert ainsi que les données du bucket, la condition matchesPrefix n'est pas requise.

Conserver les métadonnées de fichier

Pour conserver les métadonnées de fichiers, y compris les UID, GID et MODE numériques :

CLI gcloud

Utilisez le champ --preserve-metadata pour spécifier le comportement de conservation pour ce transfert. Les options qui s'appliquent aux transferts du système de fichiers sont les suivantes: gid, mode, symlink et uid.

API REST

Spécifiez les options appropriées dans un objet metadataOptions.

Pour plus d'informations, consultez la section Conserver les attributs POSIX facultatifs.

Exemple de transfert à l'aide de gcloud CLI

Dans cet exemple, nous transférons les données du répertoire /tmp/datasource sur la VM1 vers /tmp/destination sur la VM2.

  1. Configurez la source du transfert.

    1. Créez le pool d'agents sources :

      gcloud transfer agent-pools create source_agent_pool
      
    2. Sur la VM1, installez des agents pour source_agent_pool en exécutant la commande suivante :

      gcloud transfer agents install --pool=source_agent_pool \
          --count=1 \
          --mount-directories="/tmp/datasource"
      
  2. Configurez la destination du transfert.

    1. Créez le pool d'agents de destination :

      gcloud transfer agent-pools create destination_agent_pool
      
    2. Sur la VM2, installez des agents pour destination_agent_pool en exécutant la commande suivante :

      gcloud transfer agents install --pool=destination_agent_pool \
          --count=3 \
          --mount-directories="/tmp/destination"
      
  3. Créez un bucket Cloud Storage intermédiaire.

    1. Créez un bucket nommé my-intermediary-bucket .

      gcloud storage buckets create gs://my-intermediary-bucket
      
    2. Autorisez votre compte pour toutes les fonctionnalités du service de transfert de stockage en exécutant la commande suivante :

      gcloud transfer authorize --add-missing
      
  4. Créez une tâche de transfert en exécutant la commande suivante :

    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
    

Étape suivante