Der beste Weg, um Dateien zwischen S3-Buckets zu verschieben?


89

Ich möchte täglich einige Dateien aus einem Produktions-Bucket in einen Entwicklungs-Bucket kopieren.

Beispiel: Kopieren Sie ProductionBucket / Feed / Feedname / Datum in DevelopmentBucket / Feed / Feedname / Datum

Da die gewünschten Dateien so tief in der Ordnerstruktur liegen, ist es zu zeitaufwändig, zu jedem Ordner zu wechseln und ihn zu kopieren / einzufügen.

Ich habe mit dem Mounten von Laufwerken in jeden Bucket und dem Schreiben eines Windows-Batch-Skripts herumgespielt, aber das ist sehr langsam und lädt unnötigerweise alle Dateien / Ordner auf den lokalen Server herunter und sichert sie erneut.

Antworten:


110

Aktualisieren

Wie von alberge (+1) hervorgehoben, bietet die hervorragende AWS-Befehlszeilenschnittstelle heutzutage den vielseitigsten Ansatz für die Interaktion mit (fast) allen Dingen von AWS - sie deckt mittlerweile die APIs der meisten Dienste ab und bietet auch S3-Befehle auf höherer Ebene für den Umgang mit Ihren Anwendungsfall speziell, siehe AWS CLI-Referenz für S3 :

  • sync - Synchronisiert Verzeichnisse und S3-Präfixe. Ihr Anwendungsfall fällt unter Beispiel 2 (mehr feinkörnige Nutzungs mit --exclude, --includeund Präfix Handling usw. ist ebenfalls verfügbar):

    Der folgende Synchronisierungsbefehl synchronisiert Objekte unter einem bestimmten Präfix und Bucket mit Objekten unter einem anderen angegebenen Präfix und Bucket, indem s3-Objekte kopiert werden. [...]

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

Der Vollständigkeit halber möchte ich erwähnen, dass die S3-Befehle der unteren Ebene auch weiterhin über den Unterbefehl s3api verfügbar sind , mit dem jede SDK-basierte Lösung direkt in die AWS-CLI übersetzt werden kann, bevor die Funktionen der höheren Ebene schließlich übernommen werden.


Erste Antwort

Das Verschieben von Dateien zwischen S3 Eimer kann mittels der erreicht werden PUT Object - Copy API (gefolgt von DELETE Object ):

Diese Implementierung der PUT-Operation erstellt eine Kopie eines Objekts, das bereits in Amazon S3 gespeichert ist. Ein PUT-Kopiervorgang entspricht dem Ausführen eines GET und anschließend eines PUT. Durch Hinzufügen des Anforderungsheaders x-amz-copy-source kopiert die PUT-Operation das Quellobjekt in den Ziel-Bucket. Quelle

Für alle vorhandenen AWS SDKs stehen entsprechende Beispiele zur Verfügung, siehe Kopieren von Objekten in einem einzigen Vorgang . Natürlich wäre hier eine auf Skripten basierende Lösung die naheliegende erste Wahl. Daher kann das Kopieren eines Objekts mit dem AWS SDK für Ruby ein guter Ausgangspunkt sein. wenn Sie stattdessen Python bevorzugt, kann das gleiche über erreicht werden boto und natürlich sieht Methode copy_key()innerhalb Boto der S3 API - Dokumentation .

PUT ObjectKopiert nur Dateien, daher müssen Sie eine Datei DELETE Objectnach einem erfolgreichen Kopiervorgang explizit über noch löschen. Dies sind jedoch nur noch wenige Zeilen, sobald das gesamte Skript für den Bucket und die Dateinamen vorhanden ist (es gibt auch entsprechende Beispiele) siehe z. B. Löschen eines Objekts pro Anforderung ).



1
@MattDell können Sie die .NET-Antwort auf diese Frage hinzufügen?
Balexandre

1
Was daran schade ist, dass Amazon nicht genau weiß, ob der Kopierbefehl erfolgreich war oder nicht, so dass das Löschen nach dem Vorgang gefährlich erscheint.
James McMahon

Um ganz klar zu sein, habe ich mich speziell auf die Java-API bezogen. Ich habe eine separate Frage gestapelt stackoverflow.com/questions/17581582
James McMahon

Wir brauchen noch eine einfache Möglichkeit, eine einzelne ID und einen Schlüssel so zu erstellen, dass sie von einem Bucket lesen und in den anderen Bucket schreiben können. Vor allem, wenn die Eimer kontenübergreifend sind.
CMCDragonkai

65

Die neue offizielle AWS CLI unterstützt nativ die meisten Funktionen von s3cmd. Ich hatte zuvor s3cmddas Ruby AWS SDK verwendet, um solche Dinge zu tun, aber die offizielle CLI funktioniert hierfür hervorragend.

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

aws s3 sync s3://oldbucket s3://newbucket

4
Dies sollte ganz oben auf der Liste stehen. Dies ist der richtige Weg, um Buckets zu synchronisieren, und der aktuellste in all diesen Antworten.
dft

Wenn Sie Probleme mit Fehlern haben, denen der Zugriff verweigert wurde, lesen Sie diesen Blog-Beitrag. Es half. alfielapeter.com/posts/…
Crlane

3
Regionale Kopieaws s3 sync s3://my-bucket-in-eu-west1 s3://my-bucket-in-eu-central1 --source-region=eu-west-1 --region=eu-central-1
Äquivalent8

Wenn Sie diese Nacht auf dem Server 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 & ausführen
äquivalent8

@alberge Gibt es eine Möglichkeit, den Zugriffsschlüssel und das Geheimnis mithilfe eines Befehlszeilenarguments bereitzustellen?
EmptyData

28

Zum Verschieben / Kopieren von einem Bucket in einen anderen oder denselben Bucket verwende ich das s3cmd-Tool und funktioniert einwandfrei. Zum Beispiel:

s3cmd cp --recursive s3://bucket1/directory1 s3://bucket2/directory1
s3cmd mv --recursive s3://bucket1/directory1 s3://bucket2/directory1

28

Ich habe Tage damit verbracht, mein eigenes benutzerdefiniertes Tool zu schreiben, um die dafür erforderlichen Kopien zu parallelisieren, aber dann bin ich auf die Dokumentation gestoßen, wie der AWS S3 CLI-Synchronisierungsbefehl zum Synchronisieren von Buckets mit massiver Parallelisierung verwendet werden kann . Die folgenden Befehle weisen die AWS-CLI an, 1.000 Threads zum Ausführen von Jobs (jeweils eine kleine Datei oder ein Teil einer mehrteiligen Kopie) zu verwenden und 100.000 Jobs vorauszusehen:

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

Nachdem Sie diese ausgeführt haben, können Sie den einfachen Synchronisierungsbefehl wie folgt verwenden:

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

Auf einem m4.xlarge-Computer (in AWS - 4 Kerne, 16 GB RAM) stieg die Synchronisierungs- / Kopiergeschwindigkeit für meinen Fall (3-50 GB Dateien) von etwa 9,5 MB / s auf 700 + MiB / s, was einer Geschwindigkeitssteigerung von entspricht 70x über der Standardkonfiguration.

Update: Beachten Sie, dass S3CMD im Laufe der Jahre aktualisiert wurde und diese Änderungen jetzt nur wirksam werden, wenn Sie mit vielen kleinen Dateien arbeiten. Beachten Sie auch, dass S3CMD unter Windows (nur unter Windows) im Gesamtdurchsatz stark eingeschränkt ist und nur etwa 3 Gbit / s pro Prozess erreichen kann, unabhängig von der verwendeten Instanzgröße oder den verwendeten Einstellungen. Andere Systeme wie S5CMD haben das gleiche Problem. Ich habe mit dem S3-Team darüber gesprochen und sie prüfen es.


Vielen Dank, es ist Ihnen gelungen, mit Ihrer Konfiguration über 900 MiB / s zu erreichen.
Kozyr

@James: Schränkt uns die API bei der Erzielung solcher Hochgeschwindigkeitstransfers ein? Ich verwende die von AWS Java SDK vs CLI bereitgestellte Transfermanager-API von einem T2 EC2-Computer, um 2-GB-Dateien zu übertragen. Der Zeitunterschied beträgt ~ 5,5-mal (CLI - 14 Sekunden) gegenüber (SDK - 80 Sekunden). Außerdem wird im SDK keine Option für s3.max_queue_size angezeigt. Irgendwelche Kommentare?
Dwarrior

@Dwarrior, beide Einstellungen gelten für die CLI. Wenn Sie ein SDK verwenden, müssen Sie alle Anforderungswarteschlangen selbst verwalten. Der AWS-Support behauptet, unter Linux etwa 80% des maximal möglichen Durchsatzes zwischen EC2 und S3 erreicht zu haben (dh den angekündigten Durchsatz des EC2-Instanznetzwerks). Windows ist ein Bürger zweiter Klasse in AWS und kann mit den von Amazon bereitgestellten Tools nicht einmal die Hälfte davon erreichen, und es sieht so aus, als hätten sie nicht vor, dies zu beheben. :-( Bei einem T2-Computer gibt AWS nicht genau an, wie viel Bandbreite Sie erhalten, obwohl sich die Situation etwas verbessert, wenn Sie einen S3-VPC-Endpunkt einrichten.
James

@James Ich ging so weit, meine Liste von Dateien über Cluster in Spark zu parallelisieren, mit Parallelisierung innerhalb jeder Partition zu kombinieren und dann Transfermanager für parallele Uploads für eine bestimmte Datei zu verwenden. Ich sehe eine Verbesserung von 80 auf 45 Sekunden danach, aber es fehlt immer noch an der Art und Weise, wie CLI mit EC2 umgeht. Vielen Dank für dieses Setup. Die Leistung gegenüber Windows wurde ebenfalls drastisch verbessert. Im SDK können wir maximale Verbindungen festlegen, jedoch nicht die Warteschlangengröße. Ich denke, wir müssen möglicherweise damit fortfahren. :) Alle Hinweise zum Verwalten von Warteschlangen, jeder Beispielcode, den ich als Basis verwenden kann.
Dwarrior

2
S5Cmd ( github.com/peakgames/s5cmd ) ist das Dienstprogramm, das die AWS- Supportmitarbeiter für maximalen Durchsatz verwenden. Die Instanzgröße macht einen großen Unterschied. Die neue c5n-Serie ist sehr kostengünstig für das Networking und erreicht erstaunliche 100 Gbit / s.
James

13

.NET Beispiel wie gewünscht:

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

mit Client ist so etwas wie

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

Es gibt vielleicht einen besseren Weg, aber es ist nur ein kurzer Code, den ich geschrieben habe, um einige Dateien zu übertragen.


1
Das scheint eine gute Lösung zu sein. Aber was passiert, wenn Sie unterschiedliche Anmeldeinformationen für die beiden Eimer haben?
Roee Gavirel

2
Die Anmeldeinformationen dienen zur Ausführung des Kopierbefehls. Diese einzelnen Anmeldeinformationen erfordern entsprechende Lese- / Schreibberechtigungen in den Quell- / Ziel-Buckets. Um zwischen Konten zu kopieren, müssen Sie eine Bucket-Richtlinie verwenden, um den Zugriff auf den Bucket über die Anmeldeinformationen des anderen Kontos zu ermöglichen.
Matt Houser

9

Wenn Sie einen Unix-Host in AWS haben, verwenden Sie s3cmd von s3tools.org. Richten Sie Berechtigungen so ein, dass Ihr Schlüssel als Lesezugriff auf Ihren Entwicklungs-Bucket erfolgt. Dann renne:

s3cmd cp -r s3://productionbucket/feed/feedname/date s3://developmentbucket/feed/feedname

Serverseite? Es gibt keine Serverseite für s3. Alle Befehle werden von einem Remote-Client ausgeführt.
dk.

Dieser Befehl scheint übrigens über das Internet einwandfrei zu funktionieren!
Gabe Kopley

3
Die Frage "serverseitig" ist gültig. Überträgt die s3cmd-Übertragung alle Daten an den Client oder handelt es sich um eine direkte S3-zu-S3-Übertragung? In diesem Fall ist es vorzuziehen, dies in der AWS-Cloud auszuführen, um externe WAN-Übertragungen zu vermeiden.
Bruce Edge

1
Das Kopieren erfolgt alles remote auf S3.
dk.

Beachten Sie auch, dass, wenn Sie diesen Prozess versehentlich unterbrechen s3cmd cp, die --skip-existingOption nicht akzeptiert , Sie sie jedoch s3cmd syncstattdessen mit vorhandenem Überspringen
ausführen können

9

Für mich hat der folgende Befehl gerade funktioniert:

aws s3 mv s3://bucket/data s3://bucket/old_data --recursive

2
einfache und unkomplizierte Lösung ... warum Tools oder Problemumgehungen von Drittanbietern für solch einfache Aufgaben verwenden, wenn dies mit aws cli möglich ist?!
Fr0zenFyr

7

Hier ist eine Ruby-Klasse, um dies durchzuführen: https://gist.github.com/4080793

Anwendungsbeispiel:

$ 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

5

Eigentlich verwende ich seit kurzem nur die Aktion Kopieren + Einfügen in der AWS s3-Oberfläche. Navigieren Sie einfach zu den Dateien, die Sie kopieren möchten, klicken Sie auf "Aktionen" -> "Kopieren" und navigieren Sie dann zum Zielbereich und zu "Aktionen" -> "Einfügen".

Es überträgt die Dateien ziemlich schnell und es scheint eine weniger komplizierte Lösung zu sein, die keine Programmierung erfordert, oder übertriebene Lösungen wie diese.


Ja. Ich habe das vor einigen Minuten entdeckt. Ich habe gestimmt, damit mehr Leute Zeit sparen :)
JCarlosR

Ich habe das auf einem Bucket versucht, um eine Kopie mit 134.364 Objekten zu erstellen. Es dauerte Stunden. Und das Ziel endete mit nur 134.333 Dateien - die Kopie sagte, dass es "erfolgreich" war, aber es gab keine Erklärung für die fehlenden Dateien.
Warrens

Mit dem in anderen Beiträgen beschriebenen Befehl vom Typ "aws s3 sync" wurden alle 134.364 Objekte in etwa 20 Minuten kopiert.
Warrens

4

Wir hatten genau dieses Problem mit unseren ETL-Jobs bei Snowplow , also haben wir unseren parallelen Dateikopiercode (Ruby, der auf Fog basiert ) in sein eigenes Ruby-Juwel namens Sluice extrahiert :

https://github.com/snowplow/sluice

Sluice übernimmt auch das Löschen, Verschieben und Herunterladen von S3-Dateien. alle parallelisiert und mit automatischem erneuten Versuch, wenn eine Operation fehlschlägt (was überraschend oft der Fall ist). Ich hoffe es ist nützlich!



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.