Melhor maneira de mover arquivos entre depósitos S3?

89

Eu gostaria de copiar alguns arquivos de um depósito de produção para um depósito de desenvolvimento diariamente.

Por exemplo: Copie productionbucket / feed / feedname / date para developmentbucket / feed / feedname / date

Como os arquivos que desejo estão muito inseridos na estrutura de pastas, é muito demorado ir para cada pasta e copiar / colar.

Já brinquei montando drives em cada bucket e escrevendo um script de lote do Windows, mas isso é muito lento e baixa desnecessariamente todos os arquivos / pastas para o servidor local e faz o backup novamente.

Matt Dell
fonte

Respostas:

109

Atualizar

Como apontado por alberge (+1), hoje em dia a excelente AWS Command Line Interface fornece a abordagem mais versátil para interagir com (quase) todas as coisas da AWS - entretanto, ela cobre a maioria das APIs de serviços e também apresenta comandos S3 de nível superior para lidar com o seu caso de uso especificamente, consulte a referência AWS CLI para S3 :

  • sync - Sincroniza diretórios e prefixos S3. O seu uso caso é coberto por Exemplo 2 (mais fino granulado com o uso --exclude, --includee de manuseamento de prefixo etc também está disponível):

    O comando de sincronização a seguir sincroniza objetos em um prefixo e intervalo especificados com objetos em outro prefixo e intervalo especificados, copiando objetos s3. [...]

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

Para completar, mencionarei que os comandos S3 de nível inferior também estão disponíveis por meio do subcomando s3api , o que permitiria traduzir diretamente qualquer solução baseada em SDK para o AWS CLI antes de adotar sua funcionalidade de nível superior eventualmente.


Resposta Inicial

A movimentação de arquivos entre depósitos S3 pode ser realizada por meio da API PUT Object - Copy (seguida por DELETE Object ):

Esta implementação da operação PUT cria uma cópia de um objeto que já está armazenado no Amazon S3. Uma operação de cópia PUT é o mesmo que executar um GET e, em seguida, um PUT. Adicionar o cabeçalho da solicitação, x-amz-copy-source, faz com que a operação PUT copie o objeto de origem para o intervalo de destino. Fonte

Existem respectivos exemplos para todos os SDKs da AWS existentes disponíveis, consulte Copiando objetos em uma única operação . Naturalmente, uma solução baseada em script seria a primeira escolha óbvia aqui, portanto, Copiar um objeto usando o SDK da AWS para Ruby pode ser um bom ponto de partida; se você preferir Python, o mesmo pode ser feito via boto também, é claro, consulte o método copy_key()na documentação da API S3 do boto .

PUT Objectapenas copia arquivos, então você precisará excluir explicitamente um arquivo via DELETE Objectstill após uma operação de cópia bem-sucedida, mas isso será apenas mais algumas linhas uma vez que o script geral que trata do intervalo e dos nomes de arquivo esteja pronto (há respectivos exemplos também , consulte, por exemplo, Exclusão de um objeto por solicitação ).

Steffen Opel
fonte
Acabei fazendo um script da operação com o SDK da AWS no .NET
Matt Dell
1
@MattDell você pode adicionar a resposta do .NET a esta pergunta?
balexandre
1
O que é chato nisso é que a Amazon não tem muita certeza se o comando de cópia foi bem-sucedido ou não, portanto, excluir após a operação parece perigoso.
James McMahon
Só para ficar claro, eu estava me referindo especificamente à API Java. Abri uma pergunta separada stackoverflow.com/questions/17581582
James McMahon
Ainda precisamos de alguma maneira simples de fazer um único id e chave capaz de ler de um balde e gravar em outro balde. Especialmente se os baldes estiverem entre contas.
CMCDragonkai
65

O novo oficial AWS CLI oferece suporte nativo à maioria das funcionalidades do s3cmd. Eu estava usando s3cmdou o Ruby AWS SDK para fazer coisas como essa, mas a CLI oficial funciona muito bem para isso.

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

aws s3 sync s3://oldbucket s3://newbucket
AB
fonte
4
Isso deve ser votado para o topo da lista. É a maneira correta de sincronizar os buckets e o mais atualizado em todas essas respostas.
dft
Se você tiver problemas com os erros 403 de acesso negado, consulte esta postagem do blog. Ajudou. alfielapeter.com/posts/…
crlane
3
cópia de região cruzadaaws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1
equivalente
se você precisa executar esta noite de ower no servidor use 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
equivalente 8
@alberge Existe alguma maneira de fornecer chave de acesso e segredo usando o argumento da linha de comando?
EmptyData
28

Para mover / copiar de um balde para outro ou o mesmo balde, eu uso a ferramenta s3cmd e funciona bem. Por exemplo:

s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1
s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1
sgimeno
fonte
28

Passei dias escrevendo minha própria ferramenta personalizada para paralelizar as cópias necessárias para isso, mas depois encontrei a documentação sobre como fazer com que o comando AWS S3 CLI sync sincronizasse buckets com paralelização massiva . Os seguintes comandos dirão ao AWS CLI para usar 1.000 threads para executar trabalhos (cada um, um pequeno arquivo ou uma parte de uma cópia multiparte) e prever 100.000 trabalhos:

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

Depois de executá-los, você pode usar o comando de sincronização simples da seguinte maneira:

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

Em uma máquina m4.xlarge (em AWS - 4 núcleos, 16 GB de RAM), no meu caso (arquivos de 3-50 GB), a velocidade de sincronização / cópia foi de cerca de 9,5 MiB / s para 700 + MiB / s, um aumento de velocidade de 70x acima da configuração padrão.

Atualização: Observe que S3CMD foi atualizado ao longo dos anos e essas alterações agora só são eficazes quando você está trabalhando com muitos arquivos pequenos. Observe também que o S3CMD no Windows (somente no Windows) é seriamente limitado no rendimento geral e só pode atingir cerca de 3Gbps por processo, independentemente do tamanho da instância ou das configurações que você usa. Outros sistemas como o S5CMD têm o mesmo problema. Falei com a equipe do S3 sobre isso e eles estão investigando.

James
fonte
Obrigado, conseguiu mais de 900 + MiB / s com sua configuração, grande velocidade em relação ao padrão.
kozyr
@James: A API nos limita a alcançar essas transferências de alta velocidade? Estou usando a API transfermanager fornecida pelo AWS Java SDK vs CLI de uma máquina T2 EC2 para transferir arquivo de 2 GB. A diferença de tempo é de aproximadamente 5,5 vezes (CLI - 14 segundos) vs (SDK - 80 segundos). Além disso, não estou vendo nenhuma opção para s3.max_queue_size no SDK. Algum comentário?
Dwarrior
@Dwarrior, ambas as configurações são para a CLI. Ao usar um SDK, você deve gerenciar todas as filas de solicitações por conta própria. O suporte da AWS afirma ter atingido cerca de 80% da taxa de transferência máxima possível entre EC2 e S3 usando Linux (ou seja, a taxa de transferência de rede da instância EC2 anunciada). O Windows é um cidadão de segunda classe na AWS e não consegue nem a metade disso com as ferramentas fornecidas pela Amazon, e parece que eles não planejam consertar isso. :-( Com uma máquina T2, o AWS não especifica exatamente quanta largura de banda você obtém, embora as coisas melhorem um pouco se você configurar um ponto de extremidade S3 VPC.
James
@James Eu fui até o ponto de paralelizar minha lista de arquivos no cluster no Spark, combinando com a paralelização dentro de cada partição e então usando o transfermanager para uploads paralelos para qualquer arquivo. Vejo uma melhora de 80 para 45 segundos depois de fazer isso, mas ainda falta na maneira como a CLI lida com o EC2. Obrigado, por esta configuração. Ele melhorou o desempenho em relação ao Windows também drasticamente. No SDK, podemos definir conexões máximas, mas não o tamanho da fila, então acho que devemos deixar com isso. :) Quaisquer dicas sobre como gerenciar o enfileiramento, qualquer código de amostra que eu possa usar como linha de base.
Dwarrior
2
S5Cmd ( github.com/peakgames/s5cmd ) é o utilitário que o pessoal de suporte da AWS usou para obter o rendimento máximo. O tamanho da instância faz uma grande diferença. A nova série c5n é muito econômica para redes e chega a incríveis 100 Gbps.
James
13

Exemplo de .NET conforme solicitado:

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

com o cliente sendo algo como

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

Pode haver uma maneira melhor, mas é apenas um código rápido que escrevi para transferir alguns arquivos.

Matt Dell
fonte
1
Essa parece uma boa solução. mas o que acontece se você tiver credenciais diferentes para os 2 intervalos?
Roee Gavirel
2
As credenciais são para a execução do comando de cópia. Essas credenciais únicas exigem permissões de leitura / gravação apropriadas nos intervalos de origem / destino. Para copiar entre contas, você precisa usar uma política de bucket para permitir o acesso ao bucket das credenciais da outra conta.
Matt Houser
9

Se você tiver um host Unix na AWS, use s3cmd de s3tools.org. Configure permissões para que sua chave seja acesso de leitura ao intervalo de desenvolvimento. Então corra:

s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname
dk.
fonte
Lado do servidor? Não há servidor para s3. Todos os comandos são executados a partir de um cliente remoto.
dk.
A propósito, este comando parece funcionar bem na Internet!
Gabe Kopley
3
A questão do "lado do servidor" é válida. O s3cmd transfere todos os dados para o cliente ou é uma transferência direta de S3 para S3? Se for o primeiro, seria preferível executá-lo na nuvem AWS para evitar as transferências de WAN externas.
Bruce Edge,
1
A cópia acontece toda remotamente no S3.
dk.
Observe também que, se você acidentalmente interromper este processo s3cmd cpnão aceita a --skip-existingopção, você pode, no entanto, executar em s3cmd syncvez de ignorar existente
ianstarz
9

Para mim, o seguinte comando funcionou:

aws s3 mv s3://bucket/data s3://bucket/old_data --recursive
lony
fonte
2
solução simples e direta ... por que usar ferramentas de terceiros ou soluções alternativas para uma tarefa tão simples quando isso pode ser feito com aws cli ?!
Fr0zenFyr
7

Aqui está uma aula de ruby ​​para fazer isso: https://gist.github.com/4080793

Exemplo de uso:

$ 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
bantic
fonte
5

Na verdade, recentemente eu apenas usei a ação copiar + colar na interface AWS s3. Basta navegar até os arquivos que deseja copiar, clicar em "Ações" -> "Copiar" e navegar até o intervalo de destino e "Ações" -> "Colar"

Ele transfere os arquivos muito rápido e parece uma solução menos complicada que não requer nenhuma programação, ou soluções exageradas como essa.

Justin Workman
fonte
Sim. Eu descobri o mesmo há alguns minutos. Eu votei a favor, então mais pessoas vão economizar tempo :)
JCarlosR
Eu tentei isso em uma cópia de balde para balde com 134.364 objetos nele. Demorou horas. E o destino acabou ficando com apenas 134.333 arquivos - a cópia dizia que foi "Sucesso", mas não havia explicação para os arquivos ausentes.
warrens
Usando o comando do tipo "aws s3 sync" descrito em outros posts aqui, todos os 134.364 objetos foram copiados em cerca de 20 minutos.
warrens
4

Tivemos exatamente esse problema com nossos trabalhos de ETL no Snowplow , então extraímos nosso código de cópia de arquivo paralelo (Ruby, construído em cima do Fog ), em sua própria gema Ruby, chamada Sluice:

https://github.com/snowplow/sluice

Sluice também controla a exclusão, movimentação e download de arquivos S3; tudo paralelizado e com nova tentativa automática se uma operação falhar (o que acontece com uma frequência surpreendente). Espero que seja útil!

Alex Dean
fonte
1

Eu sei que este é um tópico antigo, mas para outras pessoas que chegam lá, minha sugestão é criar um trabalho agendado para copiar o conteúdo do intervalo de produção para o de desenvolvimento.

Você pode usar. Se você usar o .NET, este artigo pode ajudá-lo

https://edunyte.com/2015/03/aws-s3-copy-object-from-one-bucket-or/

Nikhil Gaur
fonte
0

Para a nova versão aws2.

aws2 s3 sync s3://SOURCE_BUCKET_NAME s3://NEW_BUCKET_NAME
Ankit Kumar Rajpoot
fonte