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


89

J'aimerais copier quotidiennement des fichiers d'un bucket de production vers un bucket de développement.

Par exemple: copiez productionbucket / feed / feedname / date dans 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 montage de lecteurs sur chaque seau et l'écriture d'un script batch Windows, mais c'est très lent et cela télécharge inutilement tous les fichiers / dossiers sur le serveur local et les sauvegarde à nouveau.

Réponses:


109

Mettre à jour

Comme le souligne alberge (+1), de nos jours, l'excellente interface de ligne de commande AWS offre l'approche la plus polyvalente pour interagir avec (presque) tout ce qui concerne AWS - elle couvre la plupart des API de services et propose également des commandes S3 de plus haut niveau pour gérer votre cas d'utilisation spécifique, consultez 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, --includeet la gestion des préfixes, etc. est également disponible):

    La commande de synchronisation suivante synchronise les objets sous un préfixe spécifié et un compartiment avec des objets sous un autre préfixe et compartiment spécifié en copiant des objets 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 également toujours disponibles via la sous-commande s3api , ce qui permettrait de traduire directement toute solution basée sur le SDK vers l'AWS CLI avant d'adopter éventuellement sa fonctionnalité de niveau supérieur.


Réponse initiale

Le déplacement de fichiers entre les compartiments S3 peut être réalisé au moyen de PUT Object - Copy API (suivi de DELETE Object ):

Cette implémentation de l'opération PUT crée une copie d'un objet qui est déjà stocké dans Amazon S3. Une opération de copie PUT équivaut à effectuer un GET puis un PUT. L'ajout de l'en-tête de demande, x-amz-copy-source, permet à l'opération PUT de copier l'objet source dans le compartiment de destination. La source

Il existe des exemples respectifs pour tous les kits SDK AWS existants, consultez Copie d'objets en une seule opération . Naturellement, une solution basée sur des scripts serait le premier choix évident ici, donc Copier un objet à l'aide du kit AWS SDK pour Ruby pourrait être un bon point de départ; si vous préférez Python à la place, la même chose peut être obtenue via boto bien sûr, voir la méthode copy_key()dans la documentation de l'API S3 de boto .

PUT Objectcopie uniquement les fichiers, vous devrez donc supprimer explicitement un fichier via DELETE Objectencore après une opération de copie réussie, mais ce ne sera que quelques lignes supplémentaires une fois que le script global gérant le bucket et les noms de fichiers sera en place (il existe également des exemples respectifs , voir par exemple Suppression d'un objet par requête ).


J'ai fini par scénariser l'opération avec le SDK AWS dans .NET
Matt Dell

1
@MattDell pouvez-vous ajouter la réponse .NET à cette question?
balexandre

1
Ce qui est nul à ce sujet, c'est qu'Amazon ne sait pas très bien si la commande de copie a réussi ou non, de sorte que la suppression après l'opération semble dangereuse.
James McMahon

Pour être clair, je faisais spécifiquement référence à l'API Java. J'ai ouvert une question distincte stackoverflow.com/questions/17581582
James McMahon

Nous avons encore besoin d'un moyen simple de créer un identifiant et une clé uniques capables de lire dans un compartiment et d'écrire dans l'autre compartiment. Surtout si les compartiments sont répartis sur plusieurs comptes.
CMCDragonkai

65

La nouvelle interface de ligne de commande AWS officielle prend en charge nativement la plupart des fonctionnalités de s3cmd. J'avais précédemment utilisé s3cmdou le kit de développement logiciel ruby AWS pour faire des choses comme celle-ci, mais la CLI officielle fonctionne très bien pour cela.

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

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

4
Cela devrait être voté en haut de la liste. C'est le bon moyen de synchroniser les buckets et le plus à jour de toutes ces réponses.
dft le

Si vous rencontrez des problèmes avec les erreurs d'accès refusé 403, consultez ce billet de blog. Ça m'a aidé. alfielapeter.com/posts/…
crlane

3
copie interrégionaleaws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1
équivalent8

si vous avez besoin d'exécuter cette ower night sur le serveur, utilisez nohup aws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1 & thegeekstuff.com/2010/12/5-ways-to-execute-linux-command
équivalent8

@alberge Existe-t-il un moyen de fournir une clé d'accès et un secret en utilisant l'argument de ligne de commande?
EmptyData

28

Pour déplacer / copier d'un seau à un autre ou au même seau, j'utilise l'outil s3cmd et fonctionne très bien. Par exemple:

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

28

J'ai passé des jours à écrire mon propre outil personnalisé pour paralléliser les copies requises pour cela, mais j'ai ensuite parcouru la documentation sur la façon d'obtenir la commande de synchronisation de l'AWS S3 CLI pour synchroniser les buckets avec une parallélisation massive . Les commandes suivantes indiqueront à l'AWS CLI d'utiliser 1 000 threads pour exécuter des tâches (chacune un petit fichier ou une partie d'une copie en plusieurs parties) et anticiper 100 000 tâches:

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

Après les avoir exécutés, 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 (dans AWS - 4 cœurs, 16 Go de RAM), pour mon cas (fichiers de 3 à 50 Go), la vitesse de synchronisation / copie est passée d'environ 9,5 Mio / s à 700 + Mio / s, soit une augmentation de vitesse de 70x sur la configuration par défaut.

Mise à jour: Notez que S3CMD a été mis à jour au fil des ans et que ces modifications ne sont désormais effectives que lorsque vous travaillez avec beaucoup de petits fichiers. Notez également que S3CMD sur Windows (uniquement sur Windows) est sérieusement limité en débit global et ne peut atteindre qu'environ 3 Gbps par processus, quelle que soit la taille de l'instance ou les paramètres que vous utilisez. D'autres systèmes comme S5CMD ont le même problème. J'en ai parlé à l'équipe S3 et ils l'examinent.


Merci, j'ai réussi à obtenir plus de 900 + Mio / s avec votre configuration, une vitesse énorme par rapport à la valeur par défaut.
kozyr

@James: L'API nous limite-t-elle à réaliser des transferts aussi rapides? J'utilise l'API transfermanager fournie par AWS Java SDK vs CLI à partir d'une machine T2 EC2 pour transférer un fichier de 2 Go. La différence de temps est d'environ 5,5 fois (CLI - 14 secondes) vs (SDK - 80 secondes). De plus, je ne vois aucune option pour s3.max_queue_size dans le SDK. Des commentaires?
Dwarrior

@Dwarrior, ces deux paramètres concernent la CLI. Lorsque vous utilisez un SDK, vous devez gérer vous-même toutes les requêtes en attente. Le support AWS prétend avoir atteint environ 80% du débit maximal possible entre EC2 et S3 à l'aide de Linux (c'est-à-dire le débit réseau de l'instance EC2 annoncé). Windows est un citoyen de deuxième classe sur AWS et ne peut même pas en obtenir la moitié avec les outils fournis par Amazon, et il semble qu'ils ne prévoient pas de résoudre ce problème. :-( Avec une machine T2, AWS ne spécifie pas exactement la quantité de bande passante que vous obtenez, bien que les choses s'améliorent quelque peu si vous configurez un point de terminaison VPC S3.
James

@James Je suis allé jusqu'à la mesure de la parallélisation de ma liste de fichiers sur un cluster dans spark, en combinant avec la parallélisation dans chaque partition, puis en utilisant transfermanager pour les téléchargements parallèles pour n'importe quel fichier donné. Je vois une amélioration de 80 à 45 secondes après avoir fait cela, mais il manque toujours la façon dont la CLI gère EC2. Merci pour cette configuration. Il a également considérablement amélioré les performances sur les fenêtres. Dans le SDK, nous pouvons définir le nombre maximal de connexions mais pas la taille de la file d'attente, je pense donc que nous devrons peut-être partir avec. :) Tout pointeur sur la façon de gérer la file d'attente, tout exemple de code que je peux utiliser comme référence.
Dwarrior

2
S5Cmd ( github.com/peakgames/s5cmd ) est l'utilitaire utilisé par les responsables du support AWS pour un débit maximal. La taille de l'instance fait une grande différence. La nouvelle série c5n est très rentable pour la mise en réseau et va jusqu'à un incroyable 100 Gbps.
James

13

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

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 certains fichiers.


1
Cela semble être une bonne solution. mais que se passe-t-il si vous avez des informations d'identification différentes pour les 2 seaux?
Roee Gavirel

2
Les informations d'identification sont pour l'exécution de la commande de copie. Ces informations d'identification uniques nécessitent des autorisations de lecture / écriture appropriées dans les compartiments source / cible. Pour copier entre les comptes, vous devez utiliser une stratégie de compartiment pour autoriser l'accès au compartiment à partir des informations d'identification de l'autre compte.
Matt Houser

9

Si vous avez un hôte Unix dans AWS, utilisez s3cmd depuis s3tools.org. Configurez les autorisations afin que votre clé soit un accès en lecture à votre bucket de développement. Puis exécutez:

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

Du côté serveur? Il n'y a pas de côté serveur pour s3. Toutes les commandes sont exécutées à partir d'un client distant.
dk.

Cette commande semble fonctionner très bien sur Internet, au fait!
Gabe Kopley

3
La question "côté serveur" est valide. Le transfert s3cmd shunt toutes les données vers le client, ou s'agit-il d'un transfert direct S3 vers S3? Dans le premier cas, il serait préférable de l'exécuter dans le cloud AWS pour éviter les transferts WAN externes.
Bruce Edge

1
La copie s'effectue à distance sur S3.
dk.

Notez également que si vous interrompez accidentellement ce processus s3cmd cpn'accepte pas l' --skip-existingoption, vous pouvez cependant exécuter à la s3cmd syncplace avec skip existant
ianstarz

9

Pour moi, la commande suivante a fonctionné:

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

2
solution simple et directe ... pourquoi utiliser des outils tiers ou des solutions de contournement pour une tâche aussi simple alors que cela peut être fait avec aws cli?!
Fr0zenFyr

7

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

5

En fait, récemment, j'utilise simplement l'action copier-coller dans l'interface AWS s3. Naviguez simplement vers les fichiers que vous souhaitez copier, cliquez sur "Actions" -> "Copier" puis accédez au bucket 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 des solutions hors pair comme celle-là.


Oui. J'ai découvert la même chose il y a quelques minutes. J'ai voté pour, donc plus de gens gagneront du temps :)
JCarlosR

J'ai essayé cela sur une copie de seau à seau avec 134 364 objets. Cela a pris des heures. Et la destination s'est retrouvée avec seulement 134 333 fichiers - la copie disait que c'était "réussi", mais il n'y avait aucune explication pour les fichiers manquants.
warrens

En utilisant la commande de type "aws s3 sync" décrite dans d'autres articles ici, les 134 364 objets ont été copiés en 20 minutes environ.
warrens

4

Nous avons eu ce problème exact avec nos travaux ETL chez Snowplow , nous avons donc extrait notre code de copie de fichier parallèle (Ruby, construit au-dessus de Fog ), dans sa propre gemme Ruby, appelée Sluice:

https://github.com/snowplow/sluice

Sluice gère également la suppression, le déplacement et le téléchargement de fichiers S3; tous parallélisés et avec réessai automatique si une opération échoue (ce qu'elle fait étonnamment souvent). J'espère que c'est utile!



En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.