Одновременная загрузка файлов на S3 с помощью PutObject aws-sdk-go-v2

Загрузка файлов в Amazon S3 (Simple Storage Service) — распространенная задача при работе с облачным хранилищем. В этой статье блога мы рассмотрим, как использовать библиотеку aws-sdk-go-v2 в Go для одновременной загрузки файлов на S3. Одновременная загрузка позволяет нам загружать несколько файлов одновременно, повышая производительность и сокращая общее время загрузки.

Методы одновременной загрузки с использованием aws-sdk-go-v2:

  1. Использование горутин и групп ожидания:

    package main
    import (
       "context"
       "fmt"
       "os"
       "sync"
       "github.com/aws/aws-sdk-go-v2/aws"
       "github.com/aws/aws-sdk-go-v2/aws/external"
       "github.com/aws/aws-sdk-go-v2/service/s3"
    )
    func main() {
       cfg, err := external.LoadDefaultAWSConfig()
       if err != nil {
           panic("failed to load AWS config")
       }
       bucket := "your-bucket-name"
       files := []string{"file1.txt", "file2.txt", "file3.txt"}
       var wg sync.WaitGroup
       for _, file := range files {
           wg.Add(1)
           go func(file string) {
               defer wg.Done()
               f, err := os.Open(file)
               if err != nil {
                   fmt.Printf("failed to open file: %s\n", file)
                   return
               }
               defer f.Close()
               client := s3.New(cfg)
               _, err = client.PutObject(context.TODO(), &s3.PutObjectInput{
                   Bucket: aws.String(bucket),
                   Key:    aws.String(file),
                   Body:   f,
               })
               if err != nil {
                   fmt.Printf("failed to upload file: %s\n", file)
                   return
               }
               fmt.Printf("uploaded file: %s\n", file)
           }(file)
       }
       wg.Wait()
    }
  2. Использование пула рабочих:

    // Define a worker function that uploads a file
    func worker(ctx context.Context, cfg aws.Config, bucket string, file string, wg *sync.WaitGroup) {
       defer wg.Done()
       f, err := os.Open(file)
       if err != nil {
           fmt.Printf("failed to open file: %s\n", file)
           return
       }
       defer f.Close()
       client := s3.New(cfg)
       _, err = client.PutObject(ctx, &s3.PutObjectInput{
           Bucket: aws.String(bucket),
           Key:    aws.String(file),
           Body:   f,
       })
       if err != nil {
           fmt.Printf("failed to upload file: %s\n", file)
           return
       }
       fmt.Printf("uploaded file: %s\n", file)
    }
    func main() {
       cfg, err := external.LoadDefaultAWSConfig()
       if err != nil {
           panic("failed to load AWS config")
       }
       bucket := "your-bucket-name"
       files := []string{"file1.txt", "file2.txt", "file3.txt"}
       numWorkers := 3
       var wg sync.WaitGroup
       ctx := context.TODO()
       // Create a worker pool
       workerPool := make(chan struct{}, numWorkers)
       for _, file := range files {
           wg.Add(1)
           workerPool <- struct{}{}
           go func(file string) {
               defer func() {
                   <-workerPool
               }()
               worker(ctx, cfg, bucket, file, &wg)
           }(file)
       }
       wg.Wait()
    }

Используя библиотеку aws-sdk-go-v2 в Go, мы можем легко загружать файлы одновременно в Amazon S3. Приведенные примеры демонстрируют два метода: использование Goroutines и WaitGroups и использование рабочего пула. Оба подхода обеспечивают эффективную одновременную загрузку, сокращая общее время загрузки. Выберите метод, который лучше всего соответствует вашим требованиям, и используйте возможности параллелизма в рабочих процессах загрузки файлов S3.

Не забудьте импортировать необходимые пакеты и настроить сегменты и имена файлов в соответствии с вашим конкретным вариантом использования. Приятного кодирования!