Utilità Amazon S3 - AWS SDK per Go v2

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Utilità Amazon S3

Gestori di trasferimenti Amazon S3

I gestori di upload e download di Amazon S3 possono suddividere oggetti di grandi dimensioni, in modo che possano essere trasferiti in più parti, in parallelo. In questo modo è facile riprendere i trasferimenti interrotti.

Gestione caricamenti Amazon S3

Il gestore di caricamento di Amazon S3 determina se un file può essere suddiviso in parti più piccole e caricato in parallelo. Puoi personalizzare il numero di caricamenti paralleli e la dimensione delle parti caricate.

L'esempio seguente utilizza Amazon S3 Uploader per caricare un file. L'utilizzo Uploader è simile all's3.PutObject()operazione.

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

Opzioni di configurazione

Quando si crea un'Uploaderistanza utilizzando NewUploader, è possibile specificare diverse opzioni di configurazione per personalizzare il modo in cui gli oggetti vengono caricati. Le opzioni vengono sovrascritte fornendo uno o più argomenti a. NewUploader Le opzioni includono:

  • PartSize— specifica la dimensione del buffer, in byte, di ogni parte da caricare. La dimensione minima per parte è di 5 MiB.

  • Concurrency— specifica il numero di parti da caricare in parallelo.

  • LeavePartsOnError— Indica se lasciare le parti caricate correttamente in Amazon S3.

Il Concurrency valore limita il numero simultaneo di caricamenti di parti che possono verificarsi per una determinata chiamata. Upload Non si tratta di un limite globale di concorrenza tra client. Modifica i valori PartSize e di Concurrency configurazione per trovare la configurazione ottimale. Ad esempio, i sistemi con connessioni a larghezza di banda elevata possono inviare parti più grandi e più caricamenti in parallelo.

Ad esempio, l'applicazione viene configurata Uploader con un'Concurrencyimpostazione di. 5 Se l'applicazione chiama poi Upload da due goroutine diverse, il risultato sono caricamenti 10 simultanei di parti (2 goroutine * 5). Concurrency

avvertimento

Si prevede che l'applicazione limiti le chiamate simultanee per evitare l'esaurimento delle risorse dell'applicazione. Upload

Di seguito è riportato un esempio per impostare la dimensione predefinita della parte durante la Uploader creazione:

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

Per ulteriori informazioni Uploader e sulle relative configurazioni, consulta Uploader nell' AWS SDK per Go API Reference.

PutObjectInput Body Field (io. ReadSeeker rispetto a IO.Reader)

Il Body campo della s3.PutObjectInput struttura è un tipo. io.Reader Tuttavia, questo campo può essere compilato con un tipo che soddisfi sia l'interfaccia che l'io.ReadSeekerio.ReaderAtinterfaccia per migliorare l'utilizzo delle risorse applicative dell'ambiente host. L'esempio seguente crea il tipo ReadSeekerAt che soddisfa entrambe le interfacce:

type ReadSeekerAt interface { io.ReadSeeker io.ReaderAt }

Per io.Reader i tipi, i byte del lettore devono essere memorizzati nel buffer prima di poter caricare la parte. Quando si aumenta il Concurrency valore PartSize o, la memoria (RAM) richiesta per il valore Uploader aumenta in modo significativo. La memoria richiesta è di circa PartSize* Concurrency. Ad esempio, se si specificano 100 MB per PartSize e 10 perConcurrency, è necessario almeno 1 GB.

Poiché un io.Reader tipo non può determinarne le dimensioni prima di leggerne i byte, Uploader non può calcolare quante parti verranno caricate. Di conseguenza, Uploader puoi raggiungere il limite di caricamento di Amazon S3 di 10.000 parti per file di grandi dimensioni se imposti un valore PartSize troppo basso. Se tenti di caricare più di 10.000 parti, il caricamento si interrompe e restituisce un errore.

Per body i valori che implementano il ReadSeekerAt tipo, Uploader non memorizza nel buffer il contenuto del corpo in memoria prima di inviarlo ad Amazon S3. Uploadercalcola il numero previsto di parti prima di caricare il file su Amazon S3. Se il valore corrente di PartSize richiede più di 10.000 parti per caricare il file, Uploader aumenta il valore della dimensione della parte in modo che siano necessarie meno parti.

Gestione dei caricamenti non riusciti

Se un caricamento su Amazon S3 fallisce, per impostazione predefinita, Uploader utilizza l'operazione Amazon AbortMultipartUpload S3 per rimuovere le parti caricate. Questa funzionalità garantisce che i caricamenti non riusciti non consumino lo storage Amazon S3.

Puoi impostare su LeavePartsOnError true in modo che Uploader non elimini le parti caricate correttamente. Ciò è utile per riprendere i caricamenti parzialmente completati. Per operare sulle parti caricate, è necessario ottenere l'indicazione UploadID del caricamento non riuscito. L'esempio seguente mostra come utilizzare il tipo di interfaccia manager.MultiUploadFailure di errore per ottenere ilUploadID.

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 }

Sovrascrivere le opzioni di caricamento per caricamento

È possibile sovrascrivere le Uploader opzioni durante la chiamata Upload fornendo uno o più argomenti al metodo. Queste sostituzioni sono modifiche sicure per la concorrenza e non influiscono sui caricamenti in corso o sulle successive chiamate al gestore. Upload Ad esempio, per sovrascrivere la configurazione per una richiesta di caricamento specifica: PartSize

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

Esempi

Caricare una cartella su Amazon S3

L'esempio seguente utilizza il path/filepath pacchetto per raccogliere in modo ricorsivo un elenco di file e caricarli nel bucket Amazon S3 specificato. Le chiavi degli oggetti Amazon S3 sono precedute dal percorso relativo del file.

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 }

Download Manager

Il gestore di Amazon S3 Downloader determina se un file può essere suddiviso in parti più piccole e scaricato in parallelo. È possibile personalizzare il numero di download paralleli e la dimensione delle parti scaricate.

Esempio: scaricare un file

L'esempio seguente utilizza Amazon S3 Downloader per scaricare un file. Using Downloader è simile a s3. GetObjectoperazione.

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

Il downloadFile parametro è un io.WriterAt tipo. L'WriterAtinterfaccia consente di Downloader scrivere più parti del file in parallelo.

Opzioni di configurazione

Quando crei un'Downloaderistanza, puoi specificare le opzioni di configurazione per personalizzare il modo in cui gli oggetti vengono scaricati:

  • PartSize— specifica la dimensione del buffer, in byte, di ogni parte da scaricare. La dimensione minima per parte è di 5 MB.

  • Concurrency— specifica il numero di parti da scaricare in parallelo.

Il Concurrency valore limita il numero simultaneo di download di parti che possono verificarsi per una determinata Download chiamata. Non si tratta di un limite globale di concorrenza tra client. Modifica i valori PartSize e di Concurrency configurazione per trovare la configurazione ottimale. Ad esempio, i sistemi con connessioni a larghezza di banda elevata possono ricevere parti più grandi e più download in parallelo.

Ad esempio, l'applicazione viene configurata Downloader con un di. Concurrency 5 L'applicazione chiama quindi Download da due goroutine diverse, il risultato saranno download 10 simultanei di parti (2 goroutine * 5). Concurrency

avvertimento

Si prevede che l'applicazione limiti le chiamate simultanee per evitare l'esaurimento delle risorse dell'applicazione. Download

Per ulteriori informazioni sulle Downloader altre opzioni di configurazione, consulta Manager.downloader nell'API Reference. AWS SDK per Go

Ignorare le opzioni del downloader per download

È possibile sovrascrivere le Downloader opzioni durante la chiamata Download fornendo uno o più argomenti funzionali al metodo. Queste sostituzioni sono modifiche sicure dal punto di vista della concorrenza e non influiscono sui caricamenti in corso o sulle successive chiamate al gestore. Download Ad esempio, per sovrascrivere la PartSize configurazione per una richiesta di caricamento specifica:

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 })
Esempi
Scarica tutti gli oggetti in un secchio

L'esempio seguente utilizza la paginazione per raccogliere un elenco di oggetti da un bucket Amazon S3. Quindi scarica ogni oggetto in un file locale.

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

GetBucketRegionè una funzione di utilità per determinare la posizione AWS della regione di un bucket Amazon S3. GetBucketRegionprende un client Amazon S3 e lo utilizza per determinare la posizione del bucket richiesto all'interno della AWS partizione associata alla regione configurata del client.

Ad esempio, per trovare la regione per il bucket: amzn-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)

Se non GetBucketRegion è in grado di risolvere la posizione di un Bucket, la funzione restituisce un tipo di BucketNotFounderrore come mostrato nell'esempio.

Input di streaming non ricercabile

Per operazioni API come PutObject andUploadPart, il client Amazon S3 si aspetta che il valore del parametro di Body input implementi l'interfaccia IO.Seeker per impostazione predefinita. L'io.Seekerinterfaccia viene utilizzata dal client per determinare la lunghezza del valore da caricare e per calcolare l'hash del payload per la firma della richiesta. Se il valore del parametro Body di input non viene implementatoio.Seeker, l'applicazione riceverà un errore.

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

È possibile modificare questo comportamento modificando il metodo operativo Middleware utilizzando le opzioni funzionali. L'APIOptionshelper With restituisce un'opzione funzionale per zero o più mutatori del middleware. Per disabilitare il client che calcola l'hash del payload e utilizzare Unsigned Payload, richiedi la firma aggiungi v4. 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, ))
avvertimento

Amazon S3 richiede che venga fornita la lunghezza del contenuto per tutti gli oggetti caricati in un bucket. Poiché il parametro Body di input non implementa l'io.Seekerinterfaccia, il client non sarà in grado di calcolare il ContentLength parametro per la richiesta. Il parametro deve essere fornito dall'applicazione. La richiesta avrà esito negativo se il ContentLength parametro non viene fornito.

Utilizza gli SDK Gestione caricamenti Amazon S3 per i caricamenti che non sono ricercabili e che non hanno una lunghezza nota.