golang高性能Amazon S3大文件高速传输插件库s3gof3r的使用

Golang高性能Amazon S3大文件高速传输插件库s3gof3r的使用

s3gof3r是一个提供快速、并行化、流水线化流式访问Amazon S3的Go语言库,它包含一个命令行工具gof3r

特性

  • 高速传输:特别对于可以利用并行性的大型S3对象,s3gof3r能够充分利用EC2实例的带宽
  • 流式上传和下载:支持Linux/Unix管道操作
  • 端到端完整性检查:在并行上传和下载时计算md5哈希值
  • 全重试机制:所有HTTP请求和每个部分都会在上传和下载时重试
  • 内存高效:用于上传和下载部分的内存会被回收利用

安装

s3gof3r需要Go 1.5或更高版本。可以使用go get从源码安装:

# 安装命令行工具gof3r
$ go get github.com/rlmcpherson/s3gof3r/gof3r

# 仅安装库用于其他Go程序
$ go get github.com/rlmcpherson/s3gof3r

命令行工具gof3r使用

# 流式上传到S3
$ <input_stream> | gof3r put -b <bucket> -k <s3_path>

# 从S3流式下载
$ gof3r get -b <bucket> -k <s3_path> | <output_stream>

# 上传文件到S3
$ gof3r cp <local_path> s3://<bucket>/<s3_path>

# 从S3下载文件
$ gof3r cp s3://<bucket>/<s3_path> <local_path>

设置AWS密钥环境变量:

$ export AWS_ACCESS_KEY_ID=<access_key>
$ export AWS_SECRET_ACCESS_KEY=<secret_key>

示例代码

package main

import (
	"log"
	"os"
	
	"github.com/rlmcpherson/s3gof3r"
)

func main() {
	// 设置AWS凭证
	keys := s3gof3r.Keys{
		AccessKey: os.Getenv("AWS_ACCESS_KEY_ID"),
		SecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
	}
	
	// 创建S3连接
	s3 := s3gof3r.New("", keys)
	
	// 打开要上传的本地文件
	file, err := os.Open("large_file.dat")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	
	// 创建S3写入器
	bucket := s3.Bucket("my-bucket")
	writer, err := bucket.PutWriter("path/to/s3_object", nil, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer writer.Close()
	
	// 流式传输文件到S3
	if _, err := io.Copy(writer, file); err != nil {
		log.Fatal(err)
	}
	
	log.Println("文件上传成功")
}

性能基准测试

在EC2实例上,gof3r可以超过1 Gbps的上传和下载速度:

# 下载测试
$ gof3r get -b test-bucket -k 8_GB_tar | pv -a | tar -x
Duration: 53.201632211s
[ 167MB/s]

# 上传测试
$ tar -cf - test_dir/ | pv -a | gof3r put -b test-bucket -k 8_GB_tar
Duration: 1m16.080800315s
[ 119MB/s]

这些测试是在m1.xlarge EC2实例上进行的,具有虚拟化的1千兆以太网接口。


更多关于golang高性能Amazon S3大文件高速传输插件库s3gof3r的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang高性能Amazon S3大文件高速传输插件库s3gof3r的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用s3gof3r实现高性能Amazon S3大文件传输

s3gof3r是一个专为高性能Amazon S3大文件传输设计的Go语言库,它通过并发上传/下载、内存优化和智能分块等机制,显著提高了大文件传输速度。

安装

go get github.com/rlmcpherson/s3gof3r

基本配置

首先需要配置AWS凭证:

import (
    "github.com/rlmcpherson/s3gof3r"
)

func getS3Config() *s3gof3r.Config {
    keys := s3gof3r.Keys{
        AccessKey: "YOUR_AWS_ACCESS_KEY",
        SecretKey: "YOUR_AWS_SECRET_KEY",
    }
    
    return s3gof3r.NewConfig(
        s3gof3r.WithLogger(s3gof3r.DefaultLogger), // 可选日志
        s3gof3r.WithConcurrency(10),               // 并发数
        s3gof3r.WithPartSize(20 * 1024 * 1024),   // 分块大小20MB
        s3gof3r.WithScheme("https"),              // 使用HTTPS
        s3gof3r.WithRegion("us-west-1"),          // 区域
    )
}

文件上传

func uploadFile(bucketName, s3Path, localPath string) error {
    // 初始化S3 bucket
    s3 := s3gof3r.New("", getS3Config())
    bucket := s3.Bucket(bucketName)
    
    // 打开本地文件
    file, err := os.Open(localPath)
    if err != nil {
        return fmt.Errorf("failed to open file: %v", err)
    }
    defer file.Close()
    
    // 创建S3写入器
    writer, err := bucket.PutWriter(s3Path, nil, nil)
    if err != nil {
        return fmt.Errorf("failed to create S3 writer: %v", err)
    }
    defer writer.Close()
    
    // 复制文件内容
    if _, err = io.Copy(writer, file); err != nil {
        return fmt.Errorf("failed to copy file to S3: %v", err)
    }
    
    return nil
}

文件下载

func downloadFile(bucketName, s3Path, localPath string) error {
    // 初始化S3 bucket
    s3 := s3gof3r.New("", getS3Config())
    bucket := s3.Bucket(bucketName)
    
    // 创建本地文件
    file, err := os.Create(localPath)
    if err != nil {
        return fmt.Errorf("failed to create local file: %v", err)
    }
    defer file.Close()
    
    // 创建S3读取器
    reader, _, err := bucket.GetReader(s3Path, nil)
    if err != nil {
        return fmt.Errorf("failed to create S3 reader: %v", err)
    }
    defer reader.Close()
    
    // 复制文件内容
    if _, err = io.Copy(file, reader); err != nil {
        return fmt.Errorf("failed to copy S3 file to local: %v", err)
    }
    
    return nil
}

高级功能

1. 进度监控

type progressReader struct {
    io.Reader
    total    int64
    current  int64
}

func (r *progressReader) Read(p []byte) (n int, err error) {
    n, err = r.Reader.Read(p)
    r.current += int64(n)
    fmt.Printf("\rDownload progress: %.2f%%", float64(r.current)/float64(r.total)*100)
    return
}

func downloadWithProgress(bucketName, s3Path, localPath string) error {
    // ...前面的初始化代码...
    
    // 获取文件大小
    head, err := bucket.Head(s3Path)
    if err != nil {
        return err
    }
    
    reader, _, err := bucket.GetReader(s3Path, nil)
    if err != nil {
        return err
    }
    defer reader.Close()
    
    progress := &progressReader{
        Reader: reader,
        total:  head.Size,
    }
    
    if _, err = io.Copy(file, progress); err != nil {
        return err
    }
    
    fmt.Println("\nDownload completed!")
    return nil
}

2. 多部分上传控制

func uploadWithCustomParts(bucketName, s3Path, localPath string) error {
    config := getS3Config()
    config.PartSize = 50 * 1024 * 1024 // 50MB分块
    config.Concurrency = 5             // 5个并发
    
    s3 := s3gof3r.New("", config)
    bucket := s3.Bucket(bucketName)
    
    file, err := os.Open(localPath)
    if err != nil {
        return err
    }
    defer file.Close()
    
    writer, err := bucket.PutWriter(s3Path, nil, nil)
    if err != nil {
        return err
    }
    defer writer.Close()
    
    _, err = io.Copy(writer, file)
    return err
}

性能优化建议

  1. 调整分块大小:对于非常大的文件(>1GB),增加分块大小(如50-100MB)可以提高性能
  2. 增加并发数:根据网络带宽和CPU能力适当增加并发数(通常10-20)
  3. 使用EC2实例:在AWS EC2上运行传输,特别是与S3在同一区域
  4. 启用压缩:对于可压缩文件类型,可以启用gzip压缩
  5. 批量操作:对于多个小文件,考虑先打包再传输

错误处理

func safeUpload(bucketName, s3Path, localPath string) error {
    s3 := s3gof3r.New("", getS3Config())
    bucket := s3.Bucket(bucketName)
    
    file, err := os.Open(localPath)
    if err != nil {
        return fmt.Errorf("file open error: %v", err)
    }
    defer file.Close()
    
    writer, err := bucket.PutWriter(s3Path, nil, nil)
    if err != nil {
        return fmt.Errorf("S3 writer creation error: %v", err)
    }
    
    // 确保在出错时中止上传
    success := false
    defer func() {
        writer.Close()
        if !success {
            bucket.Delete(s3Path) // 删除不完整的上传
        }
    }()
    
    if _, err = io.Copy(writer, file); err != nil {
        return fmt.Errorf("upload error: %v", err)
    }
    
    success = true
    return nil
}

s3gof3r相比标准AWS SDK在大文件传输场景下性能显著提升,特别适合TB级数据迁移、备份恢复等场景。通过合理配置参数,可以充分利用带宽资源,实现最快的传输速度。

回到顶部