Utilitas Amazon S3 - AWS SDK untuk Go v2

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Utilitas Amazon S3

Manajer Transfer Amazon S3

Pengelola unggahan dan unduhan Amazon S3 dapat memecah objek besar, sehingga dapat ditransfer dalam beberapa bagian, secara paralel. Ini memudahkan untuk melanjutkan transfer yang terputus.

Manajer Unggahan Amazon S3

Manajer unggahan Amazon S3 menentukan apakah file dapat dibagi menjadi bagian-bagian yang lebih kecil dan diunggah secara paralel. Anda dapat menyesuaikan jumlah upload paralel dan ukuran bagian yang diunggah.

Contoh berikut menggunakan Amazon S3 Uploader untuk mengunggah file. UploaderPenggunaannya mirip dengan s3.PutObject() operasi.

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

Opsi konfigurasi

Saat membuat instance menggunakan Uploader instance NewUploader, Anda dapat menentukan beberapa opsi konfigurasi untuk menyesuaikan cara objek diunggah. Opsi diganti dengan memberikan satu atau lebih argumen ke. NewUploader Pilihan ini meliputi:

  • PartSize- Menentukan ukuran buffer, dalam byte, dari setiap bagian untuk meng-upload. Ukuran minimum per bagian adalah 5 MiB.

  • Concurrency- Menentukan jumlah bagian untuk meng-upload secara parallel.

  • LeavePartsOnError— Menunjukkan apakah akan meninggalkan bagian yang berhasil diunggah di Amazon S3.

ConcurrencyNilai membatasi jumlah bersamaan dari bagian upload yang dapat terjadi untuk panggilan tertentuUpload. Ini bukan batas konkurensi klien global. Tweak nilai PartSize dan Concurrency konfigurasi untuk menemukan konfigurasi yang optimal. Misalnya, sistem dengan koneksi bandwidth tinggi dapat mengirim bagian yang lebih besar dan lebih banyak unggahan secara paralel.

Misalnya, aplikasi Anda mengonfigurasi Uploader dengan Concurrency pengaturan. 5 Jika aplikasi Anda kemudian memanggil Upload dari dua goroutine yang berbeda, hasilnya adalah unggahan bagian 10 bersamaan (2 goroutine* 5). Concurrency

Awas

Aplikasi Anda diharapkan membatasi panggilan bersamaan Upload untuk mencegah kehabisan sumber daya aplikasi.

Di bawah ini adalah contoh untuk mengatur ukuran bagian default selama Uploader pembuatan:

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

Untuk informasi selengkapnya tentang Uploader dan konfigurasinya, lihat Pengunggah di Referensi AWS SDK untuk Go API.

PutObjectInput Bidang Tubuh (io. ReadSeeker vs io.reader)

BodyBidang s3.PutObjectInput struct adalah io.Reader tipe. Namun, bidang ini dapat diisi dengan jenis yang memenuhi io.ReaderAt antarmuka io.ReadSeeker dan antarmuka untuk meningkatkan pemanfaatan sumber daya aplikasi dari lingkungan host. Contoh berikut menciptakan tipe ReadSeekerAt yang memenuhi kedua antarmuka:

type ReadSeekerAt interface { io.ReadSeeker io.ReaderAt }

Untuk io.Reader jenis, byte pembaca harus di-buffer dalam memori sebelum bagian dapat diunggah. Ketika Anda meningkatkan PartSize atau Concurrency nilai, memori yang diperlukan (RAM) untuk Uploader meningkat secara signifikan. Memori yang dibutuhkan kira-kira PartSize* Concurrency. Misalnya, menentukan 100 MB untuk PartSize dan 10 untukConcurrency, membutuhkan setidaknya 1 GB.

Karena suatu io.Reader tipe tidak dapat menentukan ukurannya sebelum membaca byte-nya, Uploader tidak dapat menghitung berapa banyak bagian yang akan diunggah. Akibatnya, Uploader dapat mencapai batas unggah Amazon S3 10.000 bagian untuk file besar jika Anda mengatur PartSize terlalu rendah. Jika Anda mencoba mengunggah lebih dari 10.000 bagian, unggahan berhenti dan mengembalikan kesalahan.

Untuk body nilai yang mengimplementasikan ReadSeekerAt tipe, Uploader tidak menyangga isi isi isi dalam memori sebelum mengirimnya ke Amazon S3. Uploadermenghitung jumlah bagian yang diharapkan sebelum mengunggah file ke Amazon S3. Jika nilai saat ini PartSize membutuhkan lebih dari 10.000 bagian untuk mengunggah file, Uploader tingkatkan nilai ukuran bagian sehingga lebih sedikit bagian yang diperlukan.

Menangani Unggahan Gagal

Jika unggahan ke Amazon S3 gagal, secara default, Uploader gunakan operasi Amazon AbortMultipartUpload S3 untuk menghapus bagian yang diunggah. Fungsionalitas ini memastikan bahwa unggahan yang gagal tidak menggunakan penyimpanan Amazon S3.

Anda dapat mengatur LeavePartsOnError ke true sehingga Uploader tidak menghapus bagian yang berhasil diunggah. Ini berguna untuk melanjutkan unggahan yang sebagian selesai. Untuk beroperasi pada bagian yang diunggah, Anda harus mendapatkan UploadID unggahan yang gagal. Contoh berikut menunjukkan bagaimana menggunakan jenis antarmuka manager.MultiUploadFailure kesalahan untuk mendapatkan. UploadID

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 }

Mengganti Opsi Pengunggah Per Unggahan

Anda dapat mengganti Uploader opsi saat memanggil Upload dengan memberikan satu atau beberapa argumen ke metode. Penggantian ini adalah modifikasi aman konkurensi dan tidak memengaruhi unggahan yang sedang berlangsung, atau panggilan berikutnya ke manajer. Upload Misalnya, untuk mengganti PartSize konfigurasi untuk permintaan unggahan tertentu:

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

Contoh

Unggah Folder ke Amazon S3

Contoh berikut menggunakan path/filepath paket untuk mengumpulkan daftar file secara rekursif dan mengunggahnya ke bucket Amazon S3 yang ditentukan. Kunci objek Amazon S3 diawali dengan jalur relatif 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 }

Pengelola Unduhan

Manajer Amazon S3 Downloader menentukan apakah file dapat dibagi menjadi bagian-bagian yang lebih kecil dan diunduh secara paralel. Anda dapat menyesuaikan jumlah unduhan paralel dan ukuran bagian yang diunduh.

Contoh: Download File

Contoh berikut menggunakan Amazon S3 Downloader untuk mengunduh file. Menggunakan Downloader mirip dengan s3. GetObjectoperasi.

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

downloadFileParameternya adalah io.WriterAt tipe. WriterAtAntarmuka memungkinkan Downloader untuk menulis beberapa bagian file secara paralel.

Opsi konfigurasi

Saat membuat Downloader instance, Anda dapat menentukan opsi konfigurasi untuk menyesuaikan cara objek diunduh:

  • PartSize- Menentukan ukuran buffer, dalam byte, dari setiap bagian untuk men-download. Ukuran minimum per bagian adalah 5 MB.

  • Concurrency- Menentukan jumlah bagian untuk men-download secara paralel.

ConcurrencyNilai membatasi jumlah unduhan bagian bersamaan yang dapat terjadi untuk Download panggilan tertentu. Ini bukan batas konkurensi klien global. Tweak nilai PartSize dan Concurrency konfigurasi untuk menemukan konfigurasi yang optimal. Misalnya, sistem dengan koneksi bandwidth tinggi dapat menerima bagian yang lebih besar dan lebih banyak unduhan secara paralel.

Misalnya, aplikasi Anda mengonfigurasi Downloader dengan fileConcurrency. 5 Aplikasi Anda kemudian memanggil Download dari dua goroutine yang berbeda, hasilnya akan menjadi unduhan bagian 10 bersamaan (2 goroutine* 5). Concurrency

Awas

Aplikasi Anda diharapkan membatasi panggilan bersamaan Download untuk mencegah kehabisan sumber daya aplikasi.

Untuk informasi selengkapnya tentang Downloader dan opsi konfigurasi lainnya, lihat Manager.Downloader di Referensi API. AWS SDK untuk Go

Mengganti Opsi Pengunduh Untuk Unduhan

Anda dapat mengganti Downloader opsi saat memanggil Download dengan memberikan satu atau beberapa argumen fungsional ke metode. Penggantian ini adalah modifikasi aman konkurensi dan tidak memengaruhi unggahan yang sedang berlangsung, atau Download panggilan berikutnya ke manajer. Misalnya, untuk mengganti PartSize konfigurasi untuk permintaan unggahan tertentu:

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 })
Contoh
Unduh Semua Objek dalam Ember

Contoh berikut menggunakan pagination untuk mengumpulkan daftar objek dari bucket Amazon S3. Kemudian mengunduh setiap objek ke file lokal.

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

GetBucketRegionadalah fungsi utilitas untuk menentukan lokasi AWS Wilayah Bucket Amazon S3. GetBucketRegionmengambil klien Amazon S3 dan menggunakannya untuk menentukan lokasi Bucket yang diminta dalam AWS Partisi yang terkait dengan Wilayah yang dikonfigurasi klien.

Misalnya, untuk menemukan Wilayah untuk 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)

Jika GetBucketRegion tidak dapat menyelesaikan lokasi Bucket, fungsi mengembalikan jenis BucketNotFoundkesalahan seperti yang ditunjukkan pada contoh.

Masukan Streaming yang Tidak Dapat Dicari

Untuk operasi API seperti PutObject danUploadPart, klien Amazon S3 mengharapkan nilai parameter Body input untuk mengimplementasikan antarmuka io.Seeker secara default. io.SeekerAntarmuka digunakan oleh klien untuk menentukan panjang nilai yang akan diunggah, dan untuk menghitung hash payload untuk tanda tangan permintaan. Jika nilai parameter Body input tidak diterapkanio.Seeker, aplikasi Anda akan menerima kesalahan.

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

Anda dapat mengubah perilaku ini dengan memodifikasi metode operasi Middleware menggunakan opsi fungsional. The With APIOptions helper mengembalikan opsi fungsional untuk nol atau lebih mutator middleware. Untuk menonaktifkan klien yang menghitung hash payload dan menggunakan tanda tangan permintaan Unsigned Payload add 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, ))
Awas

Amazon S3 mengharuskan panjang konten disediakan untuk semua objek yang diunggah ke bucket. Karena parameter Body input tidak mengimplementasikan io.Seeker antarmuka, klien tidak akan dapat menghitung ContentLength parameter untuk permintaan tersebut. Parameter harus disediakan oleh aplikasi. Permintaan akan gagal jika ContentLength parameter tidak disediakan.

Gunakan SDK Manajer Unggahan Amazon S3 untuk upload yang tidak dapat dicari dan tidak memiliki panjang yang diketahui.