web-dev-qa-db-fra.com

AWS S3 copie les fichiers et les dossiers entre deux compartiments

Je recherchais un outil pour m'aider à copier le contenu d'un compartiment S3 dans un second compartiment sans télécharger le contenu dans un premier temps sur un système local.

J'ai essayé l'option de copie de la console AWS S3, mais certains fichiers imbriqués ont disparu.

J'ai essayé d'utiliser Transmit app (Panic), mais la commande dupliquée copie d'abord les fichiers sur le système local, puis sur le second compartiment.

102
cnicolaou

Copier entre les godets S3

AWS (récemment) a publié une interface de ligne de commande pour la copie entre compartiments.

http://aws.Amazon.com/cli/

$ aws s3 sync s3://mybucket-src s3://mybucket-target --exclude *.tmp
..

Ceci copiera d'un compartiment cible à un autre. 

Voir la documentation ici: Documentation CLI S3

156
Layke

Un exemple simplifié utilisant le joyau aws-sdk:

AWS.config(:access_key_id => '...', :secret_access_key => '...')
s3 = AWS::S3.new
s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key')

Si vous souhaitez effectuer la copie entre différents compartiments, spécifiez le nom du compartiment cible:

s3.buckets['bucket-name'].objects['source-key'].copy_to('target-key', :bucket_name => 'target-bucket')
40
Trevor Rowe

Vous pouvez maintenant le faire depuis l'interface d'administration S3. Il suffit d'aller dans un compartiment pour sélectionner tous vos dossiers actions->copy. Puis déplacez-vous dans votre nouveau compartiment actions->paste

36
KDEx

C'est possible avec la récente gemme aws-sdk, voir l'exemple de code:

require 'aws-sdk'

AWS.config(
  :access_key_id     => '***',
  :secret_access_key => '***',
  :max_retries       => 10
)

file     = 'test_file.rb'
bucket_0 = {:name => 'bucket_from', :endpoint => 's3-eu-west-1.amazonaws.com'}
bucket_1 = {:name => 'bucket_to',   :endpoint => 's3.amazonaws.com'}

s3_interface_from = AWS::S3.new(:s3_endpoint => bucket_0[:endpoint])
bucket_from       = s3_interface_from.buckets[bucket_0[:name]]
bucket_from.objects[file].write(open(file))

s3_interface_to   = AWS::S3.new(:s3_endpoint => bucket_1[:endpoint])
bucket_to         = s3_interface_to.buckets[bucket_1[:name]]
bucket_to.objects[file].copy_from(file, {:bucket => bucket_from})

plus de détails: Comment copier un fichier sur plusieurs compartiments avec aws-s3 gem

7
Anatoly

J'ai créé un Docker exécutable of s3s3mirror tool. Utilitaire permettant de copier et de mettre en miroir un compartiment AWS S3 vers un autre.

Il est threadé pour permettre la copie parallèle et très efficace en mémoire, il réussit là où s3cmd échoue complètement.

Usage:

docker run -e AWS_ACCESS_KEY_ID=FOO -e AWS_SECRET_ACCESS_KEY=BAR pmoust/s3s3mirror [OPTIONS] source_bucket[/prefix] dest_bucket[/prefix]

Pour une liste complète des options, essayez:

docker run pmoust/s3s3mirror 
6

Copier entre les compartiments dans différentes régions

$ aws s3 cp s3://src_bucket/file  s3://dst_bucket/file --source-region eu-west-1 --region ap-northeast-1

La commande ci-dessus copie un fichier d'un seau situé en Europe (eu-west-1) vers le Japon (ap-nord-est-1). Vous pouvez obtenir le nom de code de la région de votre compartiment avec cette commande:

$ aws s3api get-bucket-location --bucket my_bucket

Par ailleurs, il est facile d’utiliser les fonctions Copier et Coller dans la console Web S3, mais il semble que le fichier soit téléchargé du compartiment source dans le navigateur, puis transféré dans le compartiment de destination. Utiliser "aws s3" était beaucoup plus rapide pour moi.

6
Adam Gawne-Cain

Consultez la documentation ci-dessous. Je suppose que c’est ce que vous recherchez . http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectCOPY.html

La S3Interface de RightAws gem a une fonction de copie qui remplit les fonctions ci-dessus.

http://rubydoc.info/gems/right_aws/3.0.0/RightAws/S3Interface#copy-instance_method

5
Josnidhin

J'imagine que vous avez probablement déjà trouvé une bonne solution, mais pour les autres personnes qui rencontrent ce problème (comme je viens de le faire), j'ai créé un utilitaire simple spécifiquement dans le but de refléter un compartiment S3 sur un autre dans une manière hautement concurrente, mais efficace en termes de CPU et de mémoire.

C'est sur github sous une licence Apache ici: https://github.com/cobbzilla/s3s3mirror

Lorsque vous avez un très grand godet et que vous recherchez des performances maximales, cela vaut peut-être la peine d'essayer.

Si vous décidez de l'essayer, merci de me le faire savoir si vous avez des commentaires.

5
cobbzilla

Si vous êtes dans Shell et que vous voulez copier plusieurs fichiers mais pas tous les fichiers: S3cmd cp --recursive s3: // BUCKET 1/OBJECT1 s3: 3

4
user1978008

J'ai écrit un script qui sauvegarde un compartiment S3: https://github.com/roseperrone/aws-backup-rake-task

#!/usr/bin/env python
from boto.s3.connection import S3Connection
import re
import datetime
import sys
import time

def main():
    s3_ID = sys.argv[1]
    s3_key = sys.argv[2]
    src_bucket_name = sys.argv[3]
    num_backup_buckets = sys.argv[4]
    connection = S3Connection(s3_ID, s3_key)
    delete_oldest_backup_buckets(connection, num_backup_buckets)
    backup(connection, src_bucket_name)

def delete_oldest_backup_buckets(connection, num_backup_buckets):
    """Deletes the oldest backup buckets such that only the newest NUM_BACKUP_BUCKETS - 1 buckets remain."""
    buckets = connection.get_all_buckets() # returns a list of bucket objects
    num_buckets = len(buckets)

    backup_bucket_names = []
    for bucket in buckets:
        if (re.search('backup-' + r'\d{4}-\d{2}-\d{2}' , bucket.name)):
            backup_bucket_names.append(bucket.name)

    backup_bucket_names.sort(key=lambda x: datetime.datetime.strptime(x[len('backup-'):17], '%Y-%m-%d').date())

    # The buckets are sorted latest to earliest, so we want to keep the last NUM_BACKUP_BUCKETS - 1
    delete = len(backup_bucket_names) - (int(num_backup_buckets) - 1)
    if delete <= 0:
        return

    for i in range(0, delete):
        print 'Deleting the backup bucket, ' + backup_bucket_names[i]
        connection.delete_bucket(backup_bucket_names[i])

def backup(connection, src_bucket_name):
    now = datetime.datetime.now()
    # the month and day must be zero-filled
    new_backup_bucket_name = 'backup-' + str('%02d' % now.year) + '-' + str('%02d' % now.month) + '-' + str(now.day);
    print "Creating new bucket " + new_backup_bucket_name
    new_backup_bucket = connection.create_bucket(new_backup_bucket_name)
    copy_bucket(src_bucket_name, new_backup_bucket_name, connection)


def copy_bucket(src_bucket_name, dst_bucket_name, connection, maximum_keys = 100):
    src_bucket = connection.get_bucket(src_bucket_name);
    dst_bucket = connection.get_bucket(dst_bucket_name);

    result_marker = ''
    while True:
        keys = src_bucket.get_all_keys(max_keys = maximum_keys, marker = result_marker)

        for k in keys:
            print 'Copying ' + k.key + ' from ' + src_bucket_name + ' to ' + dst_bucket_name

            t0 = time.clock()
            dst_bucket.copy_key(k.key, src_bucket_name, k.key)
            print time.clock() - t0, ' seconds'

        if len(keys) < maximum_keys:
            print 'Done backing up.'
            break

        result_marker = keys[maximum_keys - 1].key

if  __=='__main__':main()

J'utilise ceci dans une tâche de rake (pour une application Rails):

desc "Back up a file onto S3"
task :backup do
     S3ID = "AKIAJM3NRWC7STXWUWVQ"
     S3KEY = "0A5kuzV+E1dkaPjZxHQAezz1GlSddJd0iS5sNpry"
     SRCBUCKET = "primary-mzgd"
     NUM_BACKUP_BUCKETS = 2

     Dir.chdir("#{Rails.root}/lib/tasks")
     system "./do_backup.py #{S3ID} #{S3KEY} #{SRCBUCKET} #{NUM_BACKUP_BUCKETS}"
end
3
Rose Perrone

J'entends dire qu’il existe un module de nœud pour cela si vous êtes javascript: p

À partir de la documentation knox-copy:

knoxCopy = require 'knox-copy'

client = knoxCopy.createClient
  key: '<api-key-here>'
  secret: '<secret-here>'
  bucket: 'backups'

client.copyBucket
  fromBucket: 'uploads'
  fromPrefix: '/nom-nom'
  toPrefix: "/upload_backups/#{new Date().toISOString()}"
  (err, count) ->
     console.log "Copied #{count} files"
1
hurrymaplelad

On m'a informé que vous pouvez également faire cela en utilisant s3distcp sur un cluster EMR. Il est supposé être plus rapide pour les données contenant de gros fichiers. Cela fonctionne assez bien sur de petits ensembles de données - mais j'aurais préféré une autre solution étant donné la courbe d'apprentissage qu'il a fallu mettre en place pour si peu de données (je n'avais jamais travaillé avec EMR auparavant).

Voici un lien de la documentation AWS: http://docs.aws.Amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

Mise à jour: pour le même ensemble de données, s3s3mirror était beaucoup plus rapide que s3distcp ou AWS cli. Beaucoup plus facile à mettre en place, aussi.

1
curious_george

Copier d'un compartiment S3 vers le même ou un autre compartiment S3 sans télécharger au format local est très simple. Utilisez la commande ci-dessous Shell.

hdfs dfs -cp -f "s3://AccessKey:SecurityKey@ExternalBucket/SourceFoldername/*.*" "s3://AccessKey:SecurityKey@ExternalBucket/TargetFoldername"

Cela copiera tous les fichiers du dossier SourceFoldername du compartiment source dans le dossier TargetFoldername du compartiment cible. Dans le code ci-dessus, veuillez remplacer AccessKey, SecurityKey et ExternalBucket par vos valeurs correspondantes.

0
Sarath Avanavu

Le meilleur moyen de copier un compartiment S3 consiste à utiliser l'interface AWS CLI

Il implique ces 3 étapes:

  1. Installation de AWS CLI sur votre serveur.
**https://docs.aws.Amazon.com/cli/latest/userguide/cli-chap-install.html**
  1. Si vous copiez des compartiments entre deux comptes AWS, vous devez associer une stratégie correcte à chaque compartiment.

  2. Après cela, utilisez cette commande pour copier d’un seau à un autre.

aws s3 sync s3://sourcebucket s3://destinationbucket

Les détails de step 2 et step 3 sont donnés dans ce lien: 

https://aws.Amazon.com/premiumsupport/knowledge-center/account-transfer-s3/

0
Shubham Upadhyay

de AWS cli https://aws.Amazon.com/cli/ vous pouvez le faire

aws s3 ls - Ceci listera tous les seaux S3

aws cp --recursive s3://<source bucket> s3://<destination bucket> - Ceci copiera les fichiers d'un compartiment à un autre

Remarque * Très utile lors de la création de compartiments de réplication entre régions, en procédant comme indiqué ci-dessus, vos fichiers sont tous suivis et une mise à jour du fichier de région source sera propagée au compartiment répliqué. Tout sauf les suppressions de fichiers sont synchronisés.

Pour CRR, assurez-vous que le contrôle de version est activé sur les compartiments.

0
vredrav

Que diriez-vous de la commande aws s3 sync cli . Aws s3 sync s3: // bucket1/s3: // bucket2 /

0
user8049838

Comme Neel Bhaat l’a expliqué dans ce blog , de nombreux outils peuvent être utilisés à cette fin. Certains sont fournis par AWS, où la plupart sont des outils tiers. Tous ces outils vous obligent à enregistrer votre clé de compte AWS et votre secret dans l'outil même. Soyez très prudent lorsque vous utilisez des outils tiers, car les informations d'identification que vous enregistrez risquent de vous coûter toute votre valeur et vous feront perdre la vie.

Par conséquent, je recommande toujours d'utiliser le AWS CLI à cette fin. Vous pouvez simplement l'installer à partir de ce lien . Ensuite, exécutez la commande suivante et enregistrez votre clé, les valeurs secrètes dans AWS CLI.

aws configure

Et utilisez la commande suivante pour synchroniser votre AWS S3 Bucket sur votre ordinateur local. (AWS CLI doit être installé sur la machine locale)

aws s3 sync <source> <destination>

Exemples:

1) Pour AWS S3 sur le stockage local

aws s3 sync <S3Uri> <LocalPath>

2) Du stockage local à AWS S3

aws s3 sync <LocalPath> <S3Uri>

3) D'un seau AWS s3 à un autre.

aws s3 sync <S3Uri> <S3Uri> 
0
Keet Sugathadasa