Amazon S3 S3-Dienstprogramme - AWS SDK für Go v2

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Amazon S3 S3-Dienstprogramme

Amazon S3 S3-Übertragungsmanager

Die Upload- und Download-Manager von Amazon S3 können große Objekte aufteilen, sodass sie in mehreren Teilen parallel übertragen werden können. Dies macht es einfach, unterbrochene Übertragungen wieder aufzunehmen.

Amazon S3 S3-Uploadmanager

Der Amazon S3 S3-Upload-Manager bestimmt, ob eine Datei in kleinere Teile aufgeteilt und parallel hochgeladen werden kann. Sie können die Anzahl der parallel Uploads und die Größe der hochgeladenen Teile anpassen.

Das folgende Beispiel verwendet Amazon S3Uploader, um eine Datei hochzuladen. UploaderDie Verwendung ähnelt der s3.PutObject() Operation.

import "context" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" import "github.com/aws/aws-sdk-go-v2/feature/s3/manager" // ... cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Printf("error: %v", err) return } client := s3.NewFromConfig(cfg) uploader := manager.NewUploader(client) result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String("amzn-s3-demo-bucket"), Key: aws.String("my-object-key"), Body: uploadFile, })

Konfigurationsoptionen

Wenn Sie eine Uploader Instanz mithilfe instanziieren NewUploader, können Sie verschiedene Konfigurationsoptionen angeben, um anzupassen, wie Objekte hochgeladen werden. Optionen werden überschrieben, indem Sie ein oder mehrere Argumente für angeben. NewUploader Sie haben u. a. folgende Möglichkeiten:

  • PartSize— Gibt die Puffergröße jedes hochzuladenden Teils in Byte an. Die Mindestgröße pro Teil beträgt 5 MiB.

  • Concurrency— Gibt die Anzahl der Teile an, die parallel hochgeladen werden sollen.

  • LeavePartsOnError— Gibt an, ob erfolgreich hochgeladene Teile in Amazon S3 belassen werden sollen.

Der Concurrency Wert begrenzt die Anzahl gleichzeitiger Teil-Uploads, die bei einem bestimmten Upload Anruf durchgeführt werden können. Dies ist kein globales Limit für die Parallelität von Clients. Passen Sie die Werte PartSize und die Concurrency Konfiguration an, um die optimale Konfiguration zu finden. Beispielsweise können Systeme mit Verbindungen mit hoher Bandbreite größere Teile und mehr Uploads parallel senden.

Ihre Anwendung wird beispielsweise Uploader mit der Einstellung Concurrency of von konfiguriert. 5 Wenn Ihre Anwendung dann Upload von zwei verschiedenen Goroutinen aus aufruft, sind das Ergebnis 10 gleichzeitige Teil-Uploads (2 Goroutinen * 5). Concurrency

Warnung

Es wird erwartet, dass Ihre Anwendung die gleichzeitigen Aufrufe begrenzt, um eine Erschöpfung der Anwendungsressourcen zu verhindern. Upload

Im Folgenden finden Sie ein Beispiel für die Festlegung der Standardgröße für Bauteile bei der Uploader Erstellung:

uploader := manager.NewUploader(client, func(u *Uploader) { u.PartSize = 10 * 1024 * 1024, // 10 MiB })

Weitere Informationen zu Uploader und seinen Konfigurationen finden Sie unter Uploader in der AWS SDK für Go API-Referenz.

PutObjectInput Feld „Körper“ (io). ReadSeeker gegen io.Reader)

Das Body Feld der s3.PutObjectInput Struktur ist ein io.Reader Typ. Dieses Feld kann jedoch mit einem Typ gefüllt werden, der sowohl die io.ReaderAt Schnittstelle als auch erfüllt, um die io.ReadSeeker Nutzung der Anwendungsressourcen in der Host-Umgebung zu verbessern. Im folgenden Beispiel wird der Typ erstelltReadSeekerAt, der beide Schnittstellen erfüllt:

type ReadSeekerAt interface { io.ReadSeeker io.ReaderAt }

Bei io.Reader Typen müssen die Bytes des Lesegeräts im Speicher gepuffert werden, bevor der Teil hochgeladen werden kann. Wenn Sie den Concurrency Wert PartSize oder erhöhen, Uploader erhöht sich der benötigte Arbeitsspeicher (RAM) für erheblich. Der benötigte Arbeitsspeicher beträgt ungefähr PartSize* Concurrency. Wenn Sie beispielsweise 100 MB für PartSize und 10 für angebenConcurrency, sind mindestens 1 GB erforderlich.

Da ein io.Reader Typ seine Größe nicht vor dem Lesen seiner Byte bestimmen Uploader kann, kann nicht berechnet werden, wie viele Teile hochgeladen werden. Folglich Uploader kann das Amazon S3 S3-Upload-Limit von 10.000 Teilen für große Dateien erreicht werden, wenn Sie es PartSize zu niedrig einstellen. Wenn Sie versuchen, mehr als 10.000 Teile hochzuladen, stoppt der Upload und es wird ein Fehler zurückgegeben.

Bei body Werten, die den ReadSeekerAt Typ implementieren, Uploader puffert der den Hauptinhalt nicht im Speicher, bevor er an Amazon S3 gesendet wird. Uploaderberechnet die erwartete Anzahl von Teilen, bevor die Datei auf Amazon S3 hochgeladen wird. Wenn der aktuelle Wert von mehr als 10.000 Teile zum Hochladen der Datei PartSize erfordert, wird der Wert für die Bauteilgröße Uploader erhöht, sodass weniger Teile benötigt werden.

Umgang mit fehlgeschlagenen Uploads

Wenn ein Upload zu Amazon S3 fehlschlägt, Uploader verwendet standardmäßig den Amazon S3 AbortMultipartUpload S3-Vorgang, um die hochgeladenen Teile zu entfernen. Diese Funktion stellt sicher, dass fehlgeschlagene Uploads keinen Amazon S3 S3-Speicherplatz verbrauchen.

Sie können LeavePartsOnError den Wert auf true setzen, damit die erfolgreich hochgeladenen Teile Uploader nicht gelöscht werden. Dies ist nützlich, um teilweise abgeschlossene Uploads wieder aufzunehmen. Um mit hochgeladenen Teilen arbeiten zu können, müssen Sie die Informationen über den UploadID fehlgeschlagenen Upload erhalten. Das folgende Beispiel zeigt, wie Sie den Schnittstellentyp manager.MultiUploadFailure Fehler verwenden, um den zu ermittelnUploadID.

result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String("amzn-s3-demo-bucket"), Key: aws.String("my-object-key"), Body: uploadFile, }) output, err := u.upload(input) if err != nil { var mu manager.MultiUploadFailure if errors.As(err, &mu) { // Process error and its associated uploadID fmt.Println("Error:", mu) _ = mu.UploadID() // retrieve the associated UploadID } else { // Process error generically fmt.Println("Error:", err.Error()) } return }

Uploader-Optionen pro Upload überschreiben

Sie können die Uploader Optionen beim Aufrufen überschreiben, Upload indem Sie der Methode ein oder mehrere Argumente zur Verfügung stellen. Bei diesen Überschreibungen handelt es sich um Änderungen, bei denen die Parallelität gewährleistet ist. Sie wirken sich nicht auf laufende Uploads oder nachfolgende Aufrufe an den Manager aus. Upload Um beispielsweise die PartSize Konfiguration für eine bestimmte Upload-Anfrage zu überschreiben:

params := &s3.PutObjectInput{ Bucket: aws.String("amzn-s3-demo-bucket"), Key: aws.String("my-key"), Body: myBody, } resp, err := uploader.Upload(context.TODO(), params, func(u *manager.Uploader) { u.PartSize = 10 * 1024 * 1024, // 10 MiB })

Beispiele

Einen Ordner auf Amazon S3 hochladen

Das folgende Beispiel verwendet das path/filepath Paket, um rekursiv eine Liste von Dateien zu sammeln und sie in den angegebenen Amazon S3 S3-Bucket hochzuladen. Den Schlüsseln der Amazon S3 S3-Objekte wird der relative Pfad der Datei vorangestellt.

package main import ( "context" "log" "os" "path/filepath" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" ) var ( localPath string bucket string prefix string ) func init() { if len(os.Args) != 4 { log.Fatalln("Usage:", os.Args[0], "<local path> <bucket> <prefix>") } localPath = os.Args[1] bucket = os.Args[2] prefix = os.Args[3] } func main() { walker := make(fileWalk) go func() { // Gather the files to upload by walking the path recursively if err := filepath.Walk(localPath, walker.Walk); err != nil { log.Fatalln("Walk failed:", err) } close(walker) }() cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalln("error:", err) } // For each file found walking, upload it to Amazon S3 uploader := manager.NewUploader(s3.NewFromConfig(cfg)) for path := range walker { rel, err := filepath.Rel(localPath, path) if err != nil { log.Fatalln("Unable to get relative path:", path, err) } file, err := os.Open(path) if err != nil { log.Println("Failed opening file", path, err) continue } defer file.Close() result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: &bucket, Key: aws.String(filepath.Join(prefix, rel)), Body: file, }) if err != nil { log.Fatalln("Failed to upload", path, err) } log.Println("Uploaded", path, result.Location) } } type fileWalk chan string func (f fileWalk) Walk(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.IsDir() { f <- path } return nil }

Laden Sie den Manager herunter

Der Amazon S3 Downloader-Manager bestimmt, ob eine Datei in kleinere Teile aufgeteilt und parallel heruntergeladen werden kann. Sie können die Anzahl der parallel Downloads und die Größe der heruntergeladenen Teile anpassen.

Beispiel: Laden Sie eine Datei herunter

Im folgenden Beispiel wird Amazon S3 verwendetDownloader, um eine Datei herunterzuladen. Die Verwendung Downloader ähnelt der von S3. GetObjectBetrieb.

import "context" import "github.com/aws/aws-sdk-go-v2/aws" import "github.com/aws/aws-sdk-go-v2/config" import "github.com/aws/aws-sdk-go-v2/service/s3" import "github.com/aws/aws-sdk-go-v2/feature/s3/manager" // ... cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Println("error:", err) return } client := s3.NewFromConfig(cfg) downloader := manager.NewDownloader(client) numBytes, err := downloader.Download(context.TODO(), downloadFile, &s3.GetObjectInput{ Bucket: aws.String("amzn-s3-demo-bucket"), Key: aws.String("my-key"), })

Der downloadFile Parameter ist ein io.WriterAt Typ. Die WriterAt Schnittstelle ermöglicht esDownloader, mehrere Teile der Datei parallel zu schreiben.

Konfigurationsoptionen

Wenn Sie eine Downloader Instanz instanziieren, können Sie Konfigurationsoptionen angeben, um anzupassen, wie Objekte heruntergeladen werden:

  • PartSize— Gibt die Puffergröße jedes herunterzuladenden Teils in Byte an. Die Mindestgröße pro Teil beträgt 5 MB.

  • Concurrency— Gibt die Anzahl der Teile an, die parallel heruntergeladen werden sollen.

Der Concurrency Wert begrenzt die Anzahl der gleichzeitigen Downloads von Teilen, die bei einem bestimmten Download Anruf ausgeführt werden können. Dies ist kein globales Limit für die Parallelität von Clients. Passen Sie die Werte PartSize und die Concurrency Konfiguration an, um die optimale Konfiguration zu finden. Beispielsweise können Systeme mit Verbindungen mit hoher Bandbreite größere Teile und mehr Downloads parallel empfangen.

Ihre Anwendung wird beispielsweise Downloader mit einem Concurrency von konfiguriert. 5 Ihre Anwendung ruft dann Download von zwei verschiedenen Goroutinen aus auf. Das Ergebnis sind 10 gleichzeitige Downloads von Teilen (2 Goroutinen * 5). Concurrency

Warnung

Es wird erwartet, dass Ihre Anwendung die Anzahl gleichzeitiger Aufrufe begrenzt, um eine Erschöpfung der Anwendungsressourcen zu verhindernDownload.

Weitere Informationen zu Downloader und den anderen Konfigurationsoptionen finden Sie unter Manager.Downloader in der API-Referenz. AWS SDK für Go

Überschreiben der Downloader-Optionen pro Download

Sie können die Downloader Optionen beim Aufrufen überschreiben, Download indem Sie der Methode ein oder mehrere funktionale Argumente zur Verfügung stellen. Bei diesen Überschreibungen handelt es sich um Änderungen, die gleichzeitig funktionieren und sich nicht auf laufende Uploads oder nachfolgende Download Aufrufe an den Manager auswirken. Um beispielsweise die PartSize Konfiguration für eine bestimmte Upload-Anfrage zu überschreiben:

params := &s3.GetObjectInput{ Bucket: aws.String("amzn-s3-demo-bucket"), Key: aws.String("my-key"), } resp, err := downloader.Download(context.TODO(), targetWriter, params, func(u *manager.Downloader) { u.PartSize = 10 * 1024 * 1024, // 10 MiB })
Beispiele
Alle Objekte in einem Bucket herunterladen

Das folgende Beispiel verwendet Paginierung, um eine Liste von Objekten aus einem Amazon S3 S3-Bucket zu sammeln. Anschließend wird jedes Objekt in eine lokale Datei heruntergeladen.

package main import ( "context" "fmt" "log" "os" "path/filepath" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" ) var ( Bucket = "amzn-s3-demo-bucket" // Download from this bucket Prefix = "logs/" // Using this key prefix LocalDirectory = "s3logs" // Into this directory ) func main() { cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalln("error:", err) } client := s3.NewFromConfig(cfg) manager := manager.NewDownloader(client) paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{ Bucket: &Bucket, Prefix: &Prefix, }) for paginator.HasMorePages() { page, err := paginator.NextPage(context.TODO()) if err != nil { log.Fatalln("error:", err) } for _, obj := range page.Contents { if err := downloadToFile(manager, LocalDirectory, Bucket, aws.ToString(obj.Key)); err != nil { log.Fatalln("error:", err) } } } } func downloadToFile(downloader *manager.Downloader, targetDirectory, bucket, key string) error { // Create the directories in the path file := filepath.Join(targetDirectory, key) if err := os.MkdirAll(filepath.Dir(file), 0775); err != nil { return err } // Set up the local file fd, err := os.Create(file) if err != nil { return err } defer fd.Close() // Download the file using the AWS SDK for Go fmt.Printf("Downloading s3://%s/%s to %s...\n", bucket, key, file) _, err = downloader.Download(context.TODO(), fd, &s3.GetObjectInput{Bucket: &bucket, Key: &key}) return err }

GetBucketRegion

GetBucketRegionist eine Hilfsfunktion zur Bestimmung des Standorts der AWS Region eines Amazon S3 S3-Buckets. GetBucketRegionnimmt einen Amazon S3 S3-Client und verwendet ihn, um den Speicherort des angeforderten Buckets innerhalb der AWS Partition zu ermitteln, die der konfigurierten Region des Clients zugeordnet ist.

Um beispielsweise die Region für den Bucket zu findenamzn-s3-demo-bucket:

cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Println("error:", err) return } bucket := "amzn-s3-demo-bucket" region, err := manager.GetBucketRegion(ctx, s3.NewFromConfig(cfg), bucket) if err != nil { var bnf manager.BucketNotFound if errors.As(err, &bnf) { log.Printf("unable to find bucket %s's Region\n", bucket) } else { log.Println("error:", err) } return } fmt.Printf("Bucket %s is in %s region\n", bucket, region)

Wenn GetBucketRegion die Position eines Buckets nicht aufgelöst werden kann, gibt die Funktion einen BucketNotFoundFehlertyp zurück, wie im Beispiel gezeigt.

Streaming-Eingabe nicht auffindbar

Für API-Operationen wie PutObject und erwartet der Amazon S3 S3-ClientUploadPart, dass der Wert des Body Eingabeparameters standardmäßig die io.Seeker-Schnittstelle implementiert. Die io.Seeker Schnittstelle wird vom Client verwendet, um die Länge des hochzuladenden Werts zu bestimmen und den Payload-Hash für die Anforderungssignatur zu berechnen. Wenn der Body Eingabeparameterwert nicht implementiert wirdio.Seeker, erhält Ihre Anwendung einen Fehler.

operation error S3: PutObject, failed to compute payload hash: failed to seek body to start, request stream is not seekable

Sie können dieses Verhalten ändern, indem Sie die Betriebsmethode Middleware mithilfe von Funktionsoptionen ändern. Der APIOptionsWith-Helper gibt eine funktionale Option für null oder mehr Middleware-Mutatoren zurück. Um den Client zu deaktivieren, der den Payload-Hash berechnet und die Signatur für unsignierte Payload-Anfragen verwendet, fügen Sie v4 hinzu. SwapComputePayloadSHA256ForUnsignedPayloadMiddleware.

resp, err := client.PutObject(context.TODO(), &s3.PutObjectInput{ Bucket: &bucketName, Key: &objectName, Body: bytes.NewBuffer([]byte(`example object!`)), ContentLength: 15, // length of body }, s3.WithAPIOptions( v4.SwapComputePayloadSHA256ForUnsignedPayloadMiddleware, ))
Warnung

Amazon S3 erfordert, dass die Inhaltslänge für alle Objekte angegeben wird, die in einen Bucket hochgeladen wurden. Da der Body Eingabeparameter keine io.Seeker Schnittstelle implementiert, kann der Client den ContentLength Parameter für die Anfrage nicht berechnen. Der Parameter muss von der Anwendung bereitgestellt werden. Die Anfrage schlägt fehl, wenn der ContentLength Parameter nicht angegeben wird.

Verwenden Sie die SDKs Amazon S3 S3-Uploadmanager für Uploads, die nicht durchsuchbar sind und deren Länge nicht bekannt ist.