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.
AWS (récemment) a publié une interface de ligne de commande pour la copie entre compartiments.
$ 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
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')
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
.
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
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
$ 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.
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
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.
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
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
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"
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.
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.
Le meilleur moyen de copier un compartiment S3 consiste à utiliser l'interface AWS CLI.
Il implique ces 3 étapes:
**https://docs.aws.Amazon.com/cli/latest/userguide/cli-chap-install.html**
Si vous copiez des compartiments entre deux comptes AWS, vous devez associer une stratégie correcte à chaque compartiment.
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/
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.
Que diriez-vous de la commande aws s3 sync
cli . Aws s3 sync s3: // bucket1/s3: // bucket2 /
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>