2017-04-24 5 views
4

私はS3の互換性のあるストレージにデータのストリームを持続させようとしています。 ストリームが終了するまでのサイズは不明です。サイズは5MB〜500GBまで変更できます。S3でデータストリームを保存する方法は? aws-sdk-goの例が動作しませんか?

私はさまざまな可能性を試しましたが、自分自身でシャーディングを実装するよりも優れた解決策を見つけられませんでした。私の最高の推測では、固定サイズのバッファをストリームに埋め込んでS3に書き込むことです。 もっと良い解決策はありますか?おそらく、私はこのストリーム全体をメモリに書き込むことなく透過的な方法でしょうか?

AWS-SDK-行くReadmeには、標準入力からデータを受け取り、S3に書き込む例のprogrammがあります: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 私は何か間違っているのですか、それとも私が期待しているように動作していないのですか?

しようとしたものの

I PutObject()またはclient.PutObjectStreaming()で、minio-行きます。 これは機能的ですが、保存するデータと同程度のメモリを消費します。

  1. よりよい解決策はありますか?
  2. S3に任意のデータをパイプする小さなプログラムがありますか?

答えて

4

あなたは、未知のサイズのアップロードを処理するために、SDKのUploaderを使用することができますが、io.Readerにそれをラップすることにより、os.Stdin「unseekable」を作成する必要があります。それは、入力体もSeekerであり、それがあれば、それはそれでSeekを呼び出すんかどうかを確認するためのチェックを行いボンネットの下に、入力体としてのみio.Readerを必要としながら、これは、Uploaderです。そして、os.Stdinはインターフェイスを実装している*os.Fileなので、デフォルトではPutObjectWithContextから取得したのと同じエラーが発生します。

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より良い解決策であるかどうか、あなたは自分でテストする必要があります。

+0

ありがとうございました。私はいくつかのテストを行い、5GBまたは25GBのデータを保存するかどうかに関係なく、〜500MBの一定のメモリ使用量を得ました。これは完全ではありませんが、容認できます。 :) – xxorde

+0

私は助けることができてうれしいです。どのパーツサイズを使用していますか、並行アップロードの回数は許可していますか? – mkopriva

+0

私は同時アップロードを明示的に設定せず、20MBをPartSizeとして使用しました。私はちょうど256MBを試して、それは〜2.1 GBのメモリを消費します。 PartSize = 5MBの場合、132MBを消費します。私はここでパターンを見始めます;) – xxorde

関連する問題