Bir S3 nesnesine veri ekleyin


91

Bir S3 kovasında depolanan belirli bir günlük dosyasına yazabilmek istediğim bir makinem olduğunu varsayalım.

Bu nedenle, makinenin o kovaya yazma becerisine sahip olması gerekir, ancak bu paketteki (yazmasını istediğim dosya dahil) herhangi bir dosyanın üzerine yazma veya silme yeteneğine sahip olmasını istemiyorum.

Bu nedenle, temel olarak, makinemin, onu geçersiz kılmadan veya indirmeden, yalnızca bu günlük dosyasına veri ekleyebilmesini istiyorum.

S3'ümü bu şekilde çalışacak şekilde yapılandırmanın bir yolu var mı? Belki de istediğim gibi çalışması için ekleyebileceğim bir IAM politikası vardır?


S3'te nesneleri değiştiremezsiniz. Yeni bir günlük dosyası ekleyebilir misin? Bu daha iyi bir model olur ve aynı anda birden çok istemciyi destekler.
jarmod

@jarmod Evet, bunu düşündüm, ancak sorun şu ki, bir saldırgan sunucuma erişmeyi başarırsa, S3 klasörüne gönderilmeden önce üzerinde depolanan yerel dosyayı silebilir (diyelim ki günün sonunda olur).
Theodore

CloudWatch günlüklerine de göz atmak isteyebilirsiniz. Günlüklerinizi toplama ve saklama karmaşıklığını yönetmesine, arama olanakları, saklama politikaları sağlamasına ve günlükleriniz için özelleştirebileceğiniz ölçümlere dayalı uyarılar oluşturmanıza izin vermesine izin verin.
jarmod

1
Google BigQuery'ye de göz atabilirsiniz. Sorununuzu çözmek için kullanabilirsiniz.
Daniel777

Yanıtlar:


133

Maalesef yapamazsınız.

S3'ün "ekleme" işlemi yoktur. * Bir nesne yüklendiğinde, onu yerinde değiştirmenin bir yolu yoktur; Tek seçeneğiniz, gereksinimlerinizi karşılamayan yeni bir nesne yüklemektir.

*: Evet, bu yazının birkaç yaşında olduğunu biliyorum. Yine de doğru.


Multipart Upload kullanarak bunu başarabilir miyiz?
Anjali

1
Çok Parçalı Yükleme, orijinal nesneyi indirmeden verileri S3'e almanıza olanak tanır, ancak doğrudan orijinal nesnenin üzerine yazmanıza izin vermez. Örneğin bkz. Docs.aws.amazon.com/AmazonS3/latest/API/… Daha sonra eski nesneyi silebilir / yenisini yeniden adlandırabilirsiniz. Ancak sorunun sorduğu bu değil.
MikeGM

Multipart Upload kullanmanın gerçekten işe yarayabileceğini düşünüyorum. Tüm parçalarınız aynı dosyanın sıralı parçalarıdır. Parça yüklenmeyi başarırsa, sonunda dosyayı okuyabilmek için yüklemeyi gerçekleştirebilirsiniz. Bu nedenle, dosyanın içeriğini okumanız gerekmediği sürece, aynı çok parçalı yüklemeyi kullanmaya devam edebilirsiniz.
cerebrotecnologico

@cerebrotecnologico Hala OP'nin gereksinimlerini karşıladığını düşünmüyorum. Bir S3 kullanıcısını, bir nesneye eklenen çok parçalı yüklemeler gerçekleştirecek şekilde kısıtlamanın hiçbir yolu yok - çok parçalı bir yükleme gerçekleştirebiliyorlarsa, istedikleri herhangi bir içeriği yükleyebilirler.
alacakaranlıkta

16

Kabul edilen yanıtın da belirttiği gibi, yapamazsınız. Bildiğim en iyi çözüm şunları kullanmaktır:

AWS Kinesis Firehose

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

Onların kod örneği görünüyor karmaşık ama seninki gerçekten basit olabilir. Uygulamanızda (AWS SDK kullanarak) Kinesis Firehose teslim akışında PUT (veya BATCH PUT) işlemleri gerçekleştirmeye devam edersiniz ve Kinesis Firehose teslim akışını, akışlı verilerinizi seçtiğiniz bir AWS S3 klasörüne göndermek için AWS Kinesis Firehose konsolu).

görüntü açıklamasını buraya girin

Yine >>de Linux komut satırından olduğu kadar kullanışlı değil , çünkü S3'te bir dosya oluşturduğunuzda, yeni dosyayı indirmek, eklemek ve karşıya yüklemekle yeniden uğraşmanız gerekir, ancak bunu satırların her toplu işi için yalnızca bir kez yapmanız gerekir. her veri satırı için olduğundan daha fazla olduğundan, ekleme işlemlerinin hacmi nedeniyle büyük ücretler konusunda endişelenmenize gerek yoktur. Belki yapılabilir ama konsoldan nasıl yapılacağını göremiyorum.


8
Bunu yaparken bir maksimum süre (dosya oluşturulduktan sonra 900 saniye) veya maksimum boyut (128mb dosya boyutu) olduğunu unutmayın; yani, Kinesis yangın hortumu
Yaron Budowski

Firehose'da çıktı olarak tek bir S3 dosyası kullanabilir misiniz? Bir S3 klasöründe birden çok dosyayı birleştirme zorunluluğu biraz dağınık görünüyor.
Jón Trausti Arason

1
Ne yazık ki hayır. Ben de daha iyi bir çözüm olmasını dilerdim.
Sridhar Sarnobat

Evet talihsiz bir durum. Kayıtları manuel olarak indirip tek bir S3 nesnesine eklersem çoğunlukla yarış durumu hakkında endişeleniyorum. Kayıtları SQS'ye eklemeyi ve ardından SQS'yi yoklamak için SNS + Lambda ile biraz mantık kullanmayı ve ardından yeni girişleri S3 nesnesine yazmayı düşünüyordum.
Jón Trausti Arason

6

S3'teki nesneler eklenebilir değildir. Bu durumda 2 çözümünüz var:

  1. tüm S3 verilerini yeni bir nesneye kopyalayın, yeni içeriği ekleyin ve S3'e geri yazın.
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. İkinci seçenek Kinesis Firehose kullanmaktır. Bu oldukça basittir. Yangın hortumu dağıtım akışınızı oluşturmanız ve hedefi S3 kovasına bağlamanız gerekir. Bu kadar!
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
    }); 
}

Çıktı olarak tek bir S3 dosyası kullanabilir misiniz?
Jón Trausti Arason

1

Başkalarının daha önce de belirttiği gibi, S3 nesneleri eklenebilir değildir.
Ancak başka bir çözüm, CloudWatch günlüklerine yazmak ve ardından istediğiniz günlükleri S3'e aktarmaktır . Bu ayrıca, Lambda herhangi bir S3 izni gerektirmeyeceğinden, sunucunuza erişen tüm saldırganların S3 klasörünüzden silinmesini engeller.


1

Herhangi birinin S3 benzeri bir hizmete sahip bir nesneye veri eklemek istemesi durumunda, Alibaba Bulut OSS (Nesne Depolama Hizmeti) bunu yerel olarak destekler .

OSS, içeriği doğrudan bir nesnenin sonuna eklemenize olanak tanıyan ekleme yüklemesi (AppendObject API aracılığıyla) sağlar. Bu yöntem kullanılarak yüklenen nesneler eklenebilir nesnelerdir, diğer yöntemler kullanılarak yüklenen nesneler normal nesnelerdir. Eklenen veriler anında okunabilir.


-1

Ben de benzer bir sorun yaşadım ve sordum

AWS Lambda kullanarak dosyaya nasıl veri eklenir

İşte yukarıdaki sorunu çözmek için bulduğum şey:

Mevcut dosyadan geri dönmek için getObject kullanın

   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
});

Dosyaya eklemek için yazma işlevi

   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');
     });
}

Umarım bu yardımcı olur !!


13
Sizin writeToS3işlevi buna eklenecek bir dosyayı, üzerine yazılır.
duskwuff -inaktif-

@ duskwuff-inactive- kabul etti ve ayrıca iki yöntem aynı nesne üzerinde çalışmaya çalışırsa yarış koşullarından muzdariptir, ancak bu, değişmez dizeleri veya türleri olan dillerden gerçekten farklı değildir - geri dönerek / üzerine yazarak bir eki simüle edersiniz yeni bir nesne.
fatal_error
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.