web-dev-qa-db-ja.com

S3オブジェクトにデータを追加します

S3バケットに保存された特定のログファイルに書き込みたいマシンがあるとしましょう。

そのため、マシンにはそのバケットへの書き込み機能が必要ですが、そのバケット内のファイル(書き込み先のファイルを含む)を上書きまたは削除する機能は必要ありません。

そのため、基本的には、上書きしたりダウンロードしたりせずに、そのログファイルにのみデータを追加できるようにする必要があります。

S3をそのように動作するように設定する方法はありますか?添付できるIAMポリシーがあるので、思いどおりに機能するでしょうか?

57
Theodore

残念ながら、できません。

S3には「追加」操作はありません。* オブジェクトがアップロードされると、その場で変更する方法はありません。唯一の選択肢は、新しいオブジェクトをアップロードして置き換えることです。これは要件を満たしていません。

*:はい、この投稿は数年前のものです。ただし、まだ正確です。

87
duskwuff

受け入れられた答えが述べているように、できません。私が知っている最良の解決策は以下を使用することです:

AWS Kinesis Firehose

https://aws.Amazon.com/kinesis/firehose/

コードサンプル は複雑に見えますが、実際は単純にできます。 (AWS SDKを使用して)アプリケーションのKinesis Firehose配信ストリームに対してPUT(またはBATCH PUT)操作を実行し続け、Kinesis Firehose配信ストリームを設定して、選択したAWS S3バケットにストリーミングデータを送信します( AWS Kinesis Firehoseコンソール)。

enter image description here

Linuxコマンドラインからの>>ほど便利ではありません。S3でファイルを作成したら、新しいファイルのダウンロード、追加、アップロードを再度行う必要がありますが、行のバッチごとに1回だけ行う必要があるためです。データのすべての行に対してではなく、追加操作の量のために巨額の請求を心配する必要はありません。たぶんそれはできますが、コンソールからそれを行う方法がわかりません。

8

S3のオブジェクトは追加できません。この場合、2つのソリューションがあります。

  1. すべてのS3データを新しいオブジェクトにコピーし、新しいコンテンツを追加して、S3に書き戻します。
function writeToS3(input) {
    var content;
    var getParams = {
        Bucket: 'myBucket', 
        Key: "myKey"
    };

    s3.getObject(getParams, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            content = new Buffer(data.Body).toString("utf8");
            content = content + '\n' + new Date() + '\t' + input;
            var putParams = {
                Body: content,
                Bucket: 'myBucket', 
                Key: "myKey",
                ACL: "public-read"
             };

            s3.putObject(putParams, function(err, data) {
                if (err) console.log(err, err.stack); // an error occurred
                else     {
                    console.log(data);           // successful response
                }
             });
        }
    });  
}
  1. 2番目のオプションは、Kinesis Firehoseを使用することです。これはかなり簡単です。 Firehose配信ストリームを作成し、宛先をS3バケットにリンクする必要があります。それでおしまい!
function writeToS3(input) {
    var content = "\n" + new Date() + "\t" + input;
    var params = {
      DeliveryStreamName: 'myDeliveryStream', /* required */
      Record: { /* required */
        Data: new Buffer(content) || 'STRING_VALUE' /* Strings will be Base-64 encoded on your behalf */ /* required */
      }
    };

    firehose.putRecord(params, function(err, data) {
      if (err) console.log(err, err.stack); // an error occurred
      else     console.log(data);           // successful response
    }); 
}
3
Bharthan

私は同様の問題があり、これは私が尋ねていたものです

AWS Lambdaを使用してファイルにデータを追加する方法

上記の問題を解決するために私が思いついたものは次のとおりです。

getObjectを使用して、既存のファイルから取得します

   s3.getObject(getParams, function(err, data) {
   if (err) console.log(err, err.stack); // an error occurred
   else{
       console.log(data);           // successful response
       var s3Projects = JSON.parse(data.Body);
       console.log('s3 data==>', s3Projects);
       if(s3Projects.length > 0) {
           projects = s3Projects;
       }   
   }
   projects.Push(event);
   writeToS3(); // Calling function to append the data
});

ファイルに追加する関数を書く

   function writeToS3() {
    var putParams = {
      Body: JSON.stringify(projects),
      Bucket: bucketPath, 
      Key: "projects.json",
      ACL: "public-read"
     };

    s3.putObject(putParams, function(err, data) {
       if (err) console.log(err, err.stack); // an error occurred
       else     console.log(data);           // successful response
        callback(null, 'Hello from Lambda');
     });
}

この助けを願っています!!

0
Neeraj Kumar