Utilidades de Amazon S3 - AWS SDK para Go v2

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Utilidades de Amazon S3

Administradores de transferencias de Amazon S3

Los gestores de carga y descarga de Amazon S3 pueden dividir objetos grandes para transferirlos en varias partes, en paralelo. Esto facilita la reanudación de las transferencias interrumpidas.

Gestor de cargas de Amazon S3

El administrador de cargas de Amazon S3 determina si un archivo puede dividirse en partes más pequeñas y cargarse en paralelo. Puede personalizar el número de cargas paralelas y el tamaño de las partes cargadas.

En el siguiente ejemplo, se utiliza Amazon S3 Uploader para cargar un archivo. UploaderEl uso es similar a la s3.PutObject() operación.

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

Opciones de configuración

Al crear una Uploader instancia mediante NewUploader, puede especificar varias opciones de configuración para personalizar la forma en que se cargan los objetos. Las opciones se anulan proporcionando uno o más argumentos a. NewUploader Estas opciones son:

  • PartSize— Especifica el tamaño del búfer, en bytes, de cada parte que se va a cargar. El tamaño mínimo por pieza es de 5 MiB.

  • Concurrency— Especifica el número de piezas que se van a cargar en paralelo.

  • LeavePartsOnError— Indica si se deben dejar las piezas cargadas correctamente en Amazon S3.

El Concurrency valor limita el número simultáneo de cargas de piezas que pueden producirse en una llamada determinadaUpload. No se trata de un límite global de simultaneidad de clientes. Modifique los valores de Concurrency configuración PartSize y para encontrar la configuración óptima. Por ejemplo, los sistemas con conexiones de gran ancho de banda pueden enviar partes más grandes y más cargas en paralelo.

Por ejemplo, la aplicación se configura Uploader con un valor Concurrency de. 5 Si, a continuación, la aplicación Upload realiza llamadas desde dos rutinas diferentes, el resultado son cargas de partes 10 simultáneas (2 gorutinas * 5). Concurrency

aviso

Se espera que su aplicación limite las llamadas simultáneas para evitar el agotamiento de los recursos de la aplicación. Upload

A continuación se muestra un ejemplo para establecer el tamaño de pieza por defecto durante Uploader la creación:

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

Para obtener más información Uploader y sus configuraciones, consulte Uploader en la referencia de la AWS SDK para Go API.

PutObjectInput Body Field (io). ReadSeeker contra io.Reader)

El Body campo de la s3.PutObjectInput estructura es un tipo. io.Reader Sin embargo, este campo se puede rellenar con un tipo que satisfaga tanto la interfaz como la io.ReadSeeker io.ReaderAt interfaz para mejorar la utilización de los recursos de la aplicación en el entorno host. En el siguiente ejemplo, se crea el tipo ReadSeekerAt que satisface ambas interfaces:

type ReadSeekerAt interface { io.ReadSeeker io.ReaderAt }

En el caso de los io.Reader tipos, los bytes del lector deben almacenarse en memoria intermedia antes de poder cargar la pieza. Al aumentar el Concurrency valor PartSize o, la memoria (RAM) necesaria para ello Uploader aumenta considerablemente. La memoria requerida es aproximadamente PartSize* Concurrency. Por ejemplo, si se especifican 100 MB para PartSize y 10 paraConcurrency, se requiere al menos 1 GB.

Como un io.Reader tipo no puede determinar su tamaño antes de leer sus bytes, Uploader no puede calcular cuántas partes se cargarán. En consecuencia, Uploader puede alcanzar el límite de carga de Amazon S3 de 10 000 partes para archivos de gran tamaño si se establece un límite PartSize demasiado bajo. Si intenta cargar más de 10 000 partes, la carga se detiene y devuelve un error.

En el caso de body los valores que implementan el ReadSeekerAt tipo, Uploader no almacena en búfer el contenido del cuerpo en la memoria antes de enviarlo a Amazon S3. Uploadercalcula el número esperado de piezas antes de cargar el archivo en Amazon S3. Si el valor actual de PartSize requiere más de 10 000 partes para cargar el archivo, Uploader aumente el valor del tamaño de la pieza para que se necesiten menos piezas.

Gestión de cargas fallidas

Si se produce un error al cargar en Amazon S3, de forma predeterminada, Uploader utiliza la AbortMultipartUpload operación Amazon S3 para eliminar las partes cargadas. Esta funcionalidad garantiza que las cargas fallidas no consuman el almacenamiento de Amazon S3.

Puede establecerlo en true LeavePartsOnError para que Uploader no se eliminen las partes cargadas correctamente. Esto resulta útil para reanudar las subidas parcialmente completadas. Para operar con las partes cargadas, debe obtener la información UploadID de la carga fallida. El siguiente ejemplo muestra cómo utilizar el tipo de interfaz de manager.MultiUploadFailure error para obtener elUploadID.

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 }

Anulación de las opciones del cargador por carga

Puede anular Uploader las opciones al llamar Upload proporcionando uno o más argumentos al método. Estas anulaciones son modificaciones que garantizan la simultaneidad y no afectan a las subidas en curso ni a las llamadas posteriores al administrador. Upload Por ejemplo, para anular la configuración de una solicitud de carga específicaPartSize:

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

Ejemplos

Cargar una carpeta a Amazon S3

En el siguiente ejemplo, se utiliza el path/filepath paquete para recopilar de forma recursiva una lista de archivos y subirlos al bucket de Amazon S3 especificado. Las claves de los objetos de Amazon S3 llevan el prefijo de la ruta relativa del archivo.

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 }

Gestor de descargas

El administrador de Amazon S3 Downloader determina si un archivo puede dividirse en partes más pequeñas y descargarse en paralelo. Puede personalizar el número de descargas paralelas y el tamaño de las partes descargadas.

Ejemplo: descargar un archivo

En el siguiente ejemplo, se utiliza Amazon S3 Downloader para descargar un archivo. DownloaderEl uso es similar al s3. GetObjectoperación.

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

El downloadFile parámetro es un io.WriterAt tipo. La WriterAt interfaz permite Downloader escribir varias partes del archivo en paralelo.

Opciones de configuración

Al crear una Downloader instancia, puede especificar las opciones de configuración para personalizar la forma en que se descargan los objetos:

  • PartSize— Especifica el tamaño del búfer, en bytes, de cada parte que se va a descargar. El tamaño mínimo por parte es de 5 MB.

  • Concurrency— Especifica el número de piezas que se van a descargar en paralelo.

El Concurrency valor limita el número simultáneo de descargas de piezas que pueden producirse en una Download llamada determinada. No se trata de un límite global de simultaneidad de clientes. Modifique los valores de Concurrency configuración PartSize y para encontrar la configuración óptima. Por ejemplo, los sistemas con conexiones de gran ancho de banda pueden recibir piezas más grandes y más descargas en paralelo.

Por ejemplo, la aplicación se configura Downloader con un Concurrency de. 5 A continuación, la aplicación invoca Download desde dos goroutines diferentes y el resultado serán descargas parciales 10 simultáneas (2 goroutines * 5). Concurrency

aviso

Se espera que su aplicación limite las llamadas simultáneas para evitar el agotamiento de los recursos de la aplicación. Download

Para obtener más información Downloader y el resto de sus opciones de configuración, consulte Manager.Downloader en la referencia de la API. AWS SDK para Go

Anulación de las opciones del descargador por descarga

Puede anular Downloader las opciones al llamar Download proporcionando uno o más argumentos funcionales al método. Estas anulaciones son modificaciones seguras de la simultaneidad y no afectan a las subidas en curso ni a las Download llamadas posteriores al administrador. Por ejemplo, para anular la PartSize configuración de una solicitud de carga específica:

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 })
Ejemplos
Descarga todos los objetos de un bucket

En el siguiente ejemplo, se utiliza la paginación para recopilar una lista de objetos de un bucket de Amazon S3. A continuación, descarga cada objeto a un archivo local.

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

GetBucketRegiones una función de utilidad para determinar la ubicación AWS regional de un bucket de Amazon S3. GetBucketRegiontoma un cliente de Amazon S3 y lo usa para determinar la ubicación del bucket solicitado dentro de la AWS partición asociada a la región configurada del cliente.

Por ejemplo, para encontrar la región del bucketamzn-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)

Si no GetBucketRegion es capaz de resolver la ubicación de un cubo, la función devuelve un tipo de BucketNotFounderror, como se muestra en el ejemplo.

Entrada de streaming que no se puede buscar

Para operaciones de API como PutObject yUploadPart, el cliente Amazon S3 espera que el valor del parámetro de Body entrada implemente la interfaz io.Seeker de forma predeterminada. El cliente utiliza la io.Seeker interfaz para determinar la longitud del valor que se va a cargar y para calcular el hash de carga útil para la firma de la solicitud. Si el valor del parámetro de Body entrada no se implementaio.Seeker, la aplicación recibirá un error.

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

Puede cambiar este comportamiento modificando el método de operación Middleware mediante opciones funcionales. El APIOptions asistente With devuelve una opción funcional para cero o más mutadores de middleware. Para impedir que el cliente calcule el hash de la carga útil y utilice la firma de solicitud de carga útil sin firmar, añada la versión 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, ))
aviso

Amazon S3 requiere que se proporcione la longitud del contenido para todos los objetos cargados en un bucket. Como el parámetro de Body entrada no implementa la io.Seeker interfaz, el cliente no podrá calcular el ContentLength parámetro de la solicitud. La aplicación debe proporcionar el parámetro. La solicitud fallará si no se proporciona el ContentLength parámetro.

Usa los SDK Gestor de cargas de Amazon S3 para las cargas que no se puedan buscar y que no tengan una longitud conocida.