我正在尝试将给定的数据流持久保存到 S3 兼容存储中。
在流结束之前,大小是未知的,大小可能从 5MB 到 ~500GB 不等。
我尝试了不同的可能性,但没有找到比自己实现分片更好的解决方案。我最好的猜测是使用我的流填充固定大小的缓冲区并将其写入 S3。
有更好的解决方案吗?也许这是一种对我来说透明的方式,无需将整个流写入内存?
aws-sdk-go 自述文件有一个示例程序,它从 stdin 获取数据并将其写入 S3:https://github.com/aws/aws-sdk-go#using-the-go-sdk https://github.com/aws/aws-sdk-go#using-the-go-sdk
当我尝试用管道输入数据时|
我收到以下错误:
failed to upload object, SerializationError: failed to compute request body size
caused by: seek /dev/stdin: illegal seek
我做错了什么或者这个例子没有像我预期的那样工作吗?
我虽然尝试过 minio-go,但PutObject() https://github.com/xxorde/minio-steam-to-s3/blob/018b08b15b35ce528abc9af621bef28490fff67e/main.go or client.PutObject Streaming() https://github.com/xxorde/minio-steam-to-s3/blob/e74829acddc8f8693efc54da2d8d086d1a5e8a3f/main.go。
这是可行的,但消耗的内存与要存储的数据一样多。
- 有更好的解决方案吗?
- 是否有一个小示例程序可以将任意数据传输到 S3 中?
你可以使用sdkUploader http://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Uploader处理未知大小的上传,但您需要os.Stdin
通过将其包装成“不可查找”io.Reader
。这是因为Uploader
,虽然它只需要一个io.Reader
作为输入主体,它在底层会检查输入主体是否也是一个Seeker
如果是的话,它确实会调用Seek
在上面。自从os.Stdin
只是一个*os.File
它实现了Seeker
接口,默认情况下,你会得到与你得到的相同的错误PutObjectWithContext
.
The Uploader
还允许您以可配置大小的块的形式上传数据,并且还可以配置应同时上传的块的数量。
这是链接示例的修改版本,删除了可以保持不变的代码。
package main
import (
// ...
"io"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
type reader struct {
r io.Reader
}
func (r *reader) Read(p []byte) (int, error) {
return r.r.Read(p)
}
func main() {
// ... parse flags
sess := session.Must(session.NewSession())
uploader := s3manager.NewUploader(sess, func(u *s3manager.Uploader) {
u.PartSize = 20 << 20 // 20MB
// ... more configuration
})
// ... context stuff
_, err := uploader.UploadWithContext(ctx, &s3manager.UploadInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: &reader{os.Stdin},
})
// ... handle error
}
至于这是否是一个比minio-go
我不知道,你必须自己测试一下。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)