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
}
性能优化建议
- 调整分块大小:对于非常大的文件(>1GB),增加分块大小(如50-100MB)可以提高性能
- 增加并发数:根据网络带宽和CPU能力适当增加并发数(通常10-20)
- 使用EC2实例:在AWS EC2上运行传输,特别是与S3在同一区域
- 启用压缩:对于可压缩文件类型,可以启用gzip压缩
- 批量操作:对于多个小文件,考虑先打包再传输
错误处理
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级数据迁移、备份恢复等场景。通过合理配置参数,可以充分利用带宽资源,实现最快的传输速度。