AWS S3 copia arquivos e pastas entre dois depósitos

112

Estou procurando uma ferramenta para me ajudar a copiar o conteúdo de um bucket AWS S3 em um segundo bucket AWS S3 sem baixar o conteúdo primeiro para o sistema de arquivos local.

Tentei usar a opção de cópia do console AWS S3, mas isso resultou na falta de alguns arquivos aninhados.

Tentei usar o aplicativo Transmitir (da Panic). O comando duplicado baixa os arquivos primeiro para o sistema local e depois os carrega de volta para o segundo depósito, o que é bastante ineficiente.

cnicolaou
fonte
Considere aumentar sua contagem de solicitações simultâneas. aws configure set default.s3.max_concurrent_requests 200 Veja esta postagem para mais detalhes e opções stackoverflow.com/questions/4663016/…
Balmipour

Respostas:

176

Copiar entre Buckets S3

A AWS (recentemente) lançou uma interface de linha de comando para copiar entre baldes.

http://aws.amazon.com/cli/

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

Isso irá copiar de um intervalo de destino para outro.

Veja a documentação aqui: S3 CLI Documentation

Layke
fonte
Executei do EC2 e copiei 80 MB em cerca de 5s.
Stew-au
1
Exatamente o que eu precisava, já que o aws-sdk gem não tem nenhum recurso para copiar ou sincronizar um balde inteiro de uma vez. Obrigado!
Odigity
Ele gera o seguinte erroA client error (PermanentRedirect) occurred when calling the ListObjects operation: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
Giovanni Bitliner
@GiovanniBitliner O nome do intervalo que você está usando está incorreto. Você está usando o prefixo errado ou a maneira antiga de se referir ao intervalo. Verifique o nome do seu intervalo exatamente no console de administração.
Layke
8
Observe que se esta é a primeira vez que usa a ferramenta cli, você precisa executar 'aws configure' e inserir seus creds
S ..
41

Um exemplo simplificado usando a gem 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')

Se você deseja realizar a cópia entre diferentes intervalos, especifique o nome do intervalo de destino:

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

Agora você pode fazer isso na interface de administração do S3. Basta entrar em um balde e selecionar todas as suas pastas actions->copy. Em seguida, vá para o novo balde actions->paste.

KDEx
fonte
4
Impressionante! Ele está se referindo à interface da web. Ao contrário da maioria dos outros, eu poderia fazer isso de um iPad.
Jacob Foshee
2
Isso exclui aleatoriamente objetos aninhados em subpastas - 3 anos depois, e a AWS ainda não pode corrigir esse bug básico!
RunLoop de
é para as mesmas regiões ou todas?
hakiko
1
Esses problemas são documentados em algum lugar pela Amazon? @RunLoop
davetapley
1
@dukedave Não sei e não testei novamente por um bom tempo, pois recorri a fazer a cópia através da linha de comando, pois funcionou perfeitamente.
RunLoop
8

É possível com o aws-sdk gem recente , consulte o exemplo de código:

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

mais detalhes: Como copiar o arquivo em intervalos usando a gem aws-s3

Anatoly
fonte
Obrigado por mostrar como copiar entre servidores. Estou tentando copiar do nosso servidor para o servidor de Singapura.
Arcolye
@Arcolye, como está a latência na AWS Singapura agora? Foi lento e inconsistente há um ano.
Anatoly
7

Copiar entre intervalos em regiões diferentes

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

O comando acima copia um arquivo de um balde na Europa (eu-west-1) para o Japão (ap-northeast-1). Você pode obter o nome do código para a região do seu intervalo com este comando:

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

A propósito, usar Copiar e Colar no console da web S3 é fácil, mas parece fazer o download do balde de origem para o navegador e depois fazer o upload para o balde de destino. Usar "aws s3" foi muito mais rápido para mim.

Adam Gawne-Cain
fonte
6

Eu criei um executável Docker da ferramenta s3s3mirror . Um utilitário para copiar e espelhar de um bucket AWS S3 para outro.

Ele é encadeado permitindo a CÓPIA paralela e muito eficiente em termos de memória, é bem-sucedido onde o s3cmd falha completamente.

Uso:

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

Para obter uma lista completa de opções, tente:

docker run pmoust/s3s3mirror 
Panagiotis Moustafellos
fonte
5

Eu imagino que você provavelmente encontrou uma boa solução agora, mas para outros que estão enfrentando esse problema (como eu estava apenas recentemente), criei um utilitário simples especificamente com o propósito de espelhar um bucket S3 para outro em uma maneira altamente simultânea, mas eficiente de CPU e memória.

Está no github sob uma licença Apache aqui: https://github.com/cobbzilla/s3s3mirror

Quando você tem um balde muito grande e está procurando desempenho máximo, pode valer a pena tentar.

Se você decidir tentar, entre em contato se tiver algum feedback.

Cobbzilla
fonte
Tive uma ótima experiência com o s3s3mirror. Consegui configurá-lo em um nó EC2 m1.small e copiar 1,5 milhão de objetos em cerca de 2 horas. A configuração foi um pouco difícil, devido à minha falta de familiaridade com Maven e Java, mas bastou alguns comandos apt-get no Ubuntu para instalar tudo. Uma última observação: se (como eu) você estiver preocupado em executar um script desconhecido em um grande e importante depósito s3, crie um usuário especial com acesso somente leitura no depósito de cópia e use essas credenciais. Zero chance de exclusão acidental.
Micah
4

Se você estiver no shell e quiser copiar vários arquivos, mas não todos os arquivos: s3cmd cp --recursive s3: // BUCKET1 / OBJECT1 s3: // BUCKET2 [/ OBJECT2]

user1978008
fonte
3

Eu escrevi um script que faz backup de um intervalo 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  __name__ =='__main__':main()

Eu uso isso em uma tarefa rake (para um aplicativo 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
Rose Perrone
fonte
1

Ouvi dizer que existe um módulo de nó para isso se você gosta de javascript: p

Dos documentos do 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"
pressamaplelad
fonte
Isso não é javascript, desculpe ... (sim, estou ciente do coffeescript e você pode usá-lo, ainda assim, não é javascript)
Victor Schröder
1

Fui informado de que você também pode fazer isso usando s3distcp em um cluster EMR. É suposto ser mais rápido para dados que contêm arquivos grandes. Funciona bem o suficiente em pequenos conjuntos de dados - mas eu teria preferido outra solução dada a curva de aprendizado necessária para configurar tão poucos dados (nunca trabalhei com EMR antes).

Aqui está um link da documentação da AWS: http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

Atualização: para o mesmo conjunto de dados, o s3s3mirror foi muito mais rápido que o s3distcp ou o AWS cli. Muito mais fácil de configurar também.

George curioso
fonte
1

Para copiar de um balde S3 para o mesmo ou para outro balde S3 sem fazer download para o local, é muito simples. Use o comando shell abaixo.

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

Isso copiará todos os arquivos da SourceFoldernamepasta do intervalo de origem para a pasta do intervalo de destino TargetFoldername. No código acima, por favor, substituir AccessKey, SecurityKeye ExternalBucketcom seus valores correspondentes.

Sarath Avanavu
fonte
O que é hdfs?
Anthony Kong
1

da AWS cli https://aws.amazon.com/cli/ você poderia fazer

aws s3 ls - Isso irá listar todos os depósitos S3

aws cp --recursive s3://<source bucket> s3://<destination bucket> - Isso irá copiar os arquivos de um intervalo para outro

Nota * Muito útil ao criar depósitos de replicação entre regiões, ao fazer o acima, todos os arquivos são rastreados e uma atualização do arquivo de região de origem será propagada para o depósito replicado. Tudo, exceto as exclusões de arquivos, são sincronizados.

Para CRR, certifique-se de ter o controle de versão habilitado nos buckets.

Vredrav
fonte
0

Que tal o aws s3 synccomando cli. aws s3 sync s3: // bucket1 / s3: // bucket2 /


fonte
0

Como Neel Bhaat explicou neste blog , existem muitas ferramentas diferentes que podem ser usadas para esse fim. Alguns são fornecidos pela AWS, enquanto a maioria são ferramentas de terceiros. Todas essas ferramentas exigem que você salve a chave e o segredo da sua conta da AWS na própria ferramenta. Tenha muito cuidado ao usar ferramentas de terceiros, pois as credenciais que você salva podem custar-lhe todo o seu valor e deixá-lo morto.

Portanto, sempre recomendo usar o AWS CLI para essa finalidade. Você pode simplesmente instalar este link . Em seguida, execute o seguinte comando e salve sua chave, valores secretos no AWS CLI.

aws configure

E use o seguinte comando para sincronizar seu AWS S3 Bucket com sua máquina local. (A máquina local deve ter AWS CLI instalado)

aws s3 sync <source> <destination>

Exemplos:

1) Para AWS S3 para armazenamento local

aws s3 sync <S3Uri> <LocalPath>

2) Do armazenamento local para AWS S3

aws s3 sync <LocalPath> <S3Uri>

3) De balde AWS s3 para outro balde

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

A melhor maneira de copiar o bucket S3 é usando o AWS CLI .

Envolve estas 3 etapas:

  1. Instalando AWS CLI em seu servidor.
**https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html**
  1. Se você estiver copiando buckets entre duas contas AWS, você precisa anexar a política correta com cada bucket.

  2. Depois disso, use este comando para copiar de um intervalo para outro.

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

Os detalhes das etapas 2 e 3 são fornecidos neste link:

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

Shubham Upadhyay
fonte