Meilleur moyen de déplacer des fichiers entre des compartiments S3?

J’aimerais copier quotidiennement certains fichiers d’un compartiment de production vers un compartiment de développement.

Par exemple: Copier productionbucket / feed / feedname / date à developmentbucket / feed / feedname / date

Parce que les fichiers que je veux sont si profonds dans la structure des dossiers, il est trop long d’aller dans chaque dossier et de copier / coller.

J’ai joué avec le assembly de lecteurs sur chaque compartiment et l’écriture d’un script batch Windows, mais c’est très lent et il télécharge inutilement tous les fichiers / dossiers sur le serveur local et les sauvegarde à nouveau.

Mettre à jour

Comme l’a souligné alberge (+1), l’excellente interface de ligne de commande AWS offre de nos jours l’approche la plus polyvalente pour interagir avec (presque) tout ce qui concerne AWS. cas d’utilisation spécifique, voir la référence AWS CLI pour S3 :

  • sync – Synchronise les répertoires et les préfixes S3. Votre cas d’utilisation est couvert par l’ exemple 2 (une utilisation plus fine avec --exclude , --include et la gestion des préfixes, etc. est également disponible):

    La commande sync suivante synchronise les objects sous un préfixe et un compartiment spécifiés avec des objects situés sous un autre préfixe et un autre compartiment spécifiés en copiant les objects s3. […]

     aws s3 sync s3://from_my_bucket s3://to_my_other_bucket 

Pour être complet, je mentionnerai que les commandes S3 de niveau inférieur sont toujours disponibles via la sous-commande s3api , ce qui permettrait de traduire directement n’importe quelle solution SDK vers AWS CLI avant d’adopter ses fonctionnalités de niveau supérieur.


Réponse initiale

Déplacer des fichiers entre des compartiments S3 peut être réalisé au moyen de l’ object PUT – Copier l’API (suivi de DELETE Object ):

Cette implémentation de l’opération PUT crée une copie d’un object déjà stocké dans Amazon S3. Une opération de copie PUT est identique à l’exécution d’un GET, puis d’un PUT. L’ajout de l’en-tête de requête, x-amz-copy-source, permet à l’opération PUT de copier l’object source dans le compartiment de destination. La source

Il existe des exemples respectifs pour tous les kits SDK AWS existants, voir Copie d’objects dans une opération unique . Naturellement, une solution basée sur des scripts serait le premier choix évident ici, alors copiez un object en utilisant le kit SDK AWS pour Ruby pourrait être un bon sharepoint départ; Si vous préférez plutôt Python, vous pouvez également obtenir la même chose avec boto , voir la méthode copy_key() dans la documentation de l’API S3 de boto.

PUT Object ne copie que des fichiers, vous devrez donc supprimer explicitement un fichier via DELETE Object après une opération de copie réussie, mais ce ne sera que quelques lignes supplémentaires une fois que le script général gérant les noms de compartiment et de fichier est en place ( exemples respectifs, voir par exemple Supprimer un object par requête ).

La nouvelle interface de ligne de commande AWS officielle prend en charge la plupart des fonctionnalités de s3cmd . J’avais déjà utilisé s3cmd ou le kit AWS ruby ​​pour faire des choses comme ça, mais la CLI officielle fonctionne parfaitement pour cela.

http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html

 aws s3 sync s3://oldbucket s3://newbucket 

Pour déplacer / copier d’un seau vers un autre ou le même seau, j’utilise l’outil s3cmd et fonctionne correctement. Par exemple:

 s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1 s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1 

Exemple .NET comme demandé:

 using (client) { var existingObject = client.ListObjects(requestForExisingFile).S3Objects; if (existingObject.Count == 1) { var requestCopyObject = new CopyObjectRequest() { SourceBucket = BucketNameProd, SourceKey = objectToMerge.Key, DestinationBucket = BucketNameDev, DestinationKey = newKey }; client.CopyObject(requestCopyObject); } } 

avec le client étant quelque chose comme

 var config = new AmazonS3Config { CommunicationProtocol = Protocol.HTTP, ServiceURL = "s3-eu-west-1.amazonaws.com" }; var client = AWSClientFactory.CreateAmazonS3Client(AWSAccessKey, AWSSecretAccessKey, config); 

Il y a peut-être un meilleur moyen, mais c’est juste un code rapide que j’ai écrit pour transférer des fichiers.

J’ai passé des jours à écrire mon propre outil personnalisé pour paralléliser les copies requirejses, mais j’ai ensuite parcouru la documentation sur la façon d’obtenir la commande de synchronisation CLI AWS S3 pour synchroniser les compartiments avec une parallélisation massive . Les commandes suivantes indiquent à l’AWS CLI d’utiliser 1 000 threads pour exécuter des travaux (chacun étant un petit fichier ou une partie d’une copie multipartie) et de rechercher les 100 000 travaux suivants:

 aws configure set default.s3.max_concurrent_requests 1000 aws configure set default.s3.max_queue_size 100000 

Après leur exécution, vous pouvez utiliser la commande de synchronisation simple comme suit:

 aws s3 sync s3://source-bucket/source-path s3://destination-bucket/destination-path 

Sur une machine m4.xlarge (en AWS – 4 cœurs, 16 Go de RAM), pour mon cas (3 à 50 Go de fichiers), la vitesse de synchronisation / copie est passée d’environ 9,5 Mo / s à 700 + Mio / s, 70x sur la configuration par défaut.

Si vous avez un hôte unix dans AWS, utilisez s3cmd de s3tools.org. Configurez les permissions de manière à ce que votre clé devienne un access en lecture à votre compartiment de développement. Puis lancez:

 s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname 

Voici une classe Ruby pour effectuer ceci: https://gist.github.com/4080793

Exemple d’utilisation:

 $ gem install aws-sdk $ irb -r ./bucket_sync_service.rb > from_creds = {aws_access_key_id:"XXX", aws_secret_access_key:"YYY", bucket:"first-bucket"} > to_creds = {aws_access_key_id:"ZZZ", aws_secret_access_key:"AAA", bucket:"first-bucket"} > syncer = BucketSyncService.new(from_creds, to_creds) > syncer.debug = true # log each object > syncer.perform 

Pour moi, la commande suivante vient de fonctionner:

 aws s3 mv s3://bucket/data s3://bucket/old_data --recursive 

En fait, récemment, je viens d’utiliser l’action copier + coller dans l’interface AWS s3. Il suffit de naviguer vers les fichiers que vous souhaitez copier, cliquez sur “Actions” -> “Copier” puis accédez au compartiment de destination et “Actions” -> “Coller”

Il transfère les fichiers assez rapidement et cela semble être une solution moins compliquée qui ne nécessite aucune programmation, ou sur les meilleures solutions comme celle-là.

Nous avons eu ce problème exact avec nos travaux ETL chez Snowplow , nous avons donc extrait notre code parallèle de copie de fichiers (Ruby, construit sur le dessus de Fog ), dans son propre joyau Ruby, appelé Sluice:

https://github.com/snowplow/sluice

Sluice gère également la suppression, le déplacement et le téléchargement de fichiers S3; tout parallélisé et avec ré-essai automatique si une opération échoue (ce qui est souvent le cas). J’espère que c’est utile!

Je sais que c’est un vieux sujet, mais pour les autres, j’essaie de créer un travail planifié pour copier le contenu du compartiment de production vers le développement.

Vous pouvez utiliser Si vous utilisez .NET cet article pourrait vous aider

http://www.codewithasp.net/2015/03/aws-s3-copy-object-from-one-bucket-or.html