AWS S3 kopiuje pliki i foldery między dwoma zasobnikami


112

Szukałem narzędzia, które pomogłoby mi skopiować zawartość zasobnika AWS S3 do drugiego zasobnika AWS S3 bez wcześniejszego pobierania zawartości do lokalnego systemu plików.

Próbowałem użyć opcji kopiowania konsoli AWS S3, ale spowodowało to brak niektórych zagnieżdżonych plików.

Próbowałem użyć aplikacji Transmit (od Panic). Duplikat polecenia najpierw pobiera pliki do systemu lokalnego, a następnie przesyła je z powrotem do drugiego zasobnika, co jest dość nieefektywne.


Rozważ zwiększenie liczby jednoczesnych żądań aws configure set default.s3.max_concurrent_requests 200 Zobacz ten post, aby uzyskać więcej informacji i opcji stackoverflow.com/questions/4663016/…
Balmipour

Odpowiedzi:


176

Kopiuj między zasobnikami S3

AWS (niedawno) wypuściło interfejs wiersza poleceń do kopiowania między zasobnikami.

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

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

Spowoduje to skopiowanie z jednego zasobnika docelowego do innego zasobnika.

Zobacz dokumentację tutaj: Dokumentacja S3 CLI


Uruchomiłem go z EC2 i skopiowałem 80 MB w około 5 sekund.
Stew-au

1
Dokładnie to, czego potrzebowałem, ponieważ klejnot aws-sdk nie ma funkcji kopiowania ani synchronizowania całego wiadra naraz. Dzięki!
odigity

Wyrzuca następujący błądA 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 Nazwa zasobnika, której używasz, jest nieprawidłowa. Używasz niewłaściwego prefiksu lub starego sposobu odwoływania się do zasobnika. Sprawdź dokładnie nazwę swojego zasobnika w konsoli administracyjnej.
Layke

8
Zauważ, że jeśli używasz narzędzia CLI po raz pierwszy, musisz uruchomić „aws configure” i wprowadzić swoje dane
S ..

41

Uproszczony przykład wykorzystujący 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')

Jeśli chcesz wykonać kopię między różnymi zasobnikami, określ nazwę zasobnika docelowego:

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

41

Możesz to teraz zrobić z poziomu interfejsu administratora S3. Po prostu przejdź do jednego zasobnika i wybierz wszystkie swoje foldery actions->copy. Następnie przejdź do nowego wiadra actions->paste.


4
Niesamowite! Ma na myśli interfejs sieciowy. W przeciwieństwie do większości innych mogłem to zrobić z iPada.
Jacob Foshee

2
To losowo pomija zagnieżdżone obiekty w podfolderach - 3 lata później, a AWS nadal nie może naprawić tak podstawowego błędu!
RunLoop

czy dotyczy to tych samych regionów czy wszystkich?
hakiko,

1
Czy te problemy zostały gdzieś udokumentowane przez Amazon? @RunLoop
davetapley

1
@dukedave Nie wiem i nie testowałem ponownie od dłuższego czasu, ponieważ uciekłem się do kopiowania za pomocą wiersza poleceń, ponieważ działało to idealnie.
RunLoop

8

Jest to możliwe dzięki najnowszemu klejnotowi aws-sdk , zobacz przykład kodu:

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

więcej szczegółów: Jak skopiować plik między zasobnikami za pomocą narzędzia aws-s3 gem


Dziękuję za pokazanie, jak kopiować między serwerami. Próbuję skopiować z naszego serwera na serwer singapurski.
Arcolye

@Arcolye, jakie są teraz opóźnienia w AWS Singapore? Rok temu było powolne i niespójne.
Anatolij

7

Kopiuj między zasobnikami w różnych regionach

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

Powyższe polecenie kopiuje plik z zasobnika w Europie (eu-west-1) do Japonii (ap-północny-wschód-1). Możesz uzyskać nazwę kodową regionu swojego wiadra za pomocą tego polecenia:

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

Nawiasem mówiąc, użycie funkcji Kopiuj i wklej w konsoli internetowej S3 jest łatwe, ale wydaje się, że pobiera się z zasobnika źródłowego do przeglądarki, a następnie przesyła do zasobnika docelowego. Korzystanie z „aws s3” było dla mnie znacznie szybsze.


6

Stworzyłem Docker wykonywalny z s3s3mirror narzędzia. Narzędzie do kopiowania i tworzenia kopii lustrzanych z zasobnika AWS S3 na inny.

Jest wątkowany, umożliwiając równoległe kopiowanie i bardzo wydajny w pamięci, udaje się tam, gdzie s3cmd całkowicie zawodzi.

Stosowanie:

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

Aby zobaczyć pełną listę opcji, wypróbuj:

docker run pmoust/s3s3mirror 


5

Wyobrażam sobie, że prawdopodobnie znalazłeś już dobre rozwiązanie, ale dla innych, którzy napotykają ten problem (tak jak niedawno), stworzyłem proste narzędzie specjalnie do celów tworzenia kopii lustrzanych jednego wiadra S3 do drugiego w wysoce współbieżny, ale efektywny procesora i pamięci.

Jest na github na licencji Apache tutaj: https://github.com/cobbzilla/s3s3mirror

Jeśli masz bardzo dużą łyżkę i szukasz maksymalnej wydajności, warto spróbować.

Jeśli zdecydujesz się spróbować, daj mi znać, jeśli masz jakieś uwagi.


Miałem świetne doświadczenia z s3s3mirror. Udało mi się ustawić go na m1.small węzeł EC2 i skopiować 1,5 miliona obiektów w około 2 godziny. Konfiguracja była trochę trudna z powodu mojej nieznajomości z Maven i Javą, ale wystarczyło kilka poleceń apt-get w systemie Ubuntu, aby zainstalować wszystko. Ostatnia uwaga: jeśli (tak jak ja) martwisz się uruchomieniem nieznanego skryptu na dużym, ważnym zasobniku s3, utwórz specjalnego użytkownika z dostępem tylko do odczytu do zasobnika kopiowania i użyj tych poświadczeń. Zero szans na przypadkowe usunięcie.
Micah

4

Jeśli jesteś w powłoce i chcesz skopiować wiele plików, ale nie wszystkie pliki: s3cmd cp --recursive s3: // BUCKET1 / OBJECT1 s3: // BUCKET2 [/ OBJECT2]


3

Napisałem skrypt, który tworzy kopię zapasową wiadra 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()

Używam tego w zadaniu rake (dla aplikacji Railsowej):

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

1

Słyszałem, że jest do tego moduł węzła, jeśli interesujesz się javascript: p

Z dokumentów 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"

To nie jest javascript, przepraszam ... (tak, znam coffeescript i że możesz go używać, nadal nie javascript)
Victor Schröder

1

Poinformowano mnie, że możesz to również zrobić za pomocą s3distcp na klastrze EMR. Ma działać szybciej dla danych zawierających duże pliki. Działa wystarczająco dobrze na małych zestawach danych - ale wolałbym inne rozwiązanie, biorąc pod uwagę krzywą uczenia się potrzebną do skonfigurowania tak małych danych (nigdy wcześniej nie pracowałem z EMR).

Oto link z Dokumentacji AWS: http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/UsingEMR_s3distcp.html

Aktualizacja: dla tego samego zestawu danych s3s3mirror był znacznie szybszy niż s3distcp lub AWS cli. Dużo łatwiejsze do skonfigurowania.


1

Kopiowanie z jednego zasobnika S3 do tego samego lub innego zasobnika S3 bez pobierania do lokalnego jest całkiem proste. Użyj poniższego polecenia powłoki.

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

Spowoduje to skopiowanie wszystkich plików z SourceFoldernamefolderu zasobnika źródłowego do folderu zasobnika docelowego TargetFoldername. W powyższym kodzie, należy wymienić AccessKey, SecurityKeya ExternalBucketze swoimi odpowiednimi wartościami.


Co to jest hdfs?
Anthony Kong

1

z AWS cli https://aws.amazon.com/cli/, co możesz zrobić

aws s3 ls - Spowoduje to wyświetlenie wszystkich łyżek S3

aws cp --recursive s3://<source bucket> s3://<destination bucket> - Spowoduje to skopiowanie plików z jednego zasobnika do drugiego

Uwaga * Bardzo przydatne podczas tworzenia zasobników replikacji między regionami, wykonując powyższe czynności, wszystkie pliki są śledzone, a aktualizacja pliku regionu źródłowego zostanie propagowana do zasobnika replikowanego. Synchronizowane są wszystko oprócz usunięcia plików.

W przypadku CRR upewnij się, że masz włączoną obsługę wersji w zasobnikach.


0

Co powiesz na aws s3 syncpolecenie CLI. aws s3 sync s3: // bucket1 / s3: // bucket2 /


0

Jak wyjaśnił Neel Bhaat na tym blogu , istnieje wiele różnych narzędzi, których można użyć w tym celu. Niektóre z nich są dostarczane przez AWS, a większość z nich to narzędzia innych firm. Wszystkie te narzędzia wymagają zapisania klucza i tajnego konta AWS w samym narzędziu. Zachowaj ostrożność podczas korzystania z narzędzi stron trzecich, ponieważ dane uwierzytelniające, które zapisujesz, mogą cię kosztować całą twoją wartość i spowodować śmierć.

Dlatego zawsze zalecam używanie do tego celu AWS CLI . Możesz to po prostu zainstalować z tego linku . Następnie uruchom następujące polecenie i zapisz klucz, tajne wartości w interfejsie wiersza polecenia AWS.

aws configure

I użyj następującego polecenia, aby zsynchronizować wiadro AWS S3 z komputerem lokalnym. (Na komputerze lokalnym powinien być zainstalowany interfejs wiersza poleceń AWS)

aws s3 sync <source> <destination>

Przykłady:

1) W przypadku AWS S3 do pamięci lokalnej

aws s3 sync <S3Uri> <LocalPath>

2) Z lokalnego magazynu do AWS S3

aws s3 sync <LocalPath> <S3Uri>

3) Z wiadra AWS s3 do innego wiadra

aws s3 sync <S3Uri> <S3Uri> 

0

Najlepszym sposobem skopiowania zasobnika S3 jest użycie interfejsu wiersza polecenia AWS .

Obejmuje następujące 3 kroki:

  1. Instalowanie interfejsu wiersza polecenia AWS na serwerze.
**https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html**
  1. Jeśli kopiujesz zasobniki między dwoma kontami AWS, musisz dołączyć odpowiednią politykę do każdego zasobnika.

  2. Następnie użyj tego polecenia, aby skopiować z jednego zasobnika do drugiego.

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

Szczegóły kroku 2 i kroku 3 są podane w tym linku:

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


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.