Tambahkan data ke objek S3


91

Katakanlah saya memiliki mesin yang saya inginkan untuk dapat menulis ke file log tertentu yang disimpan di bucket S3.

Jadi, mesin harus memiliki kemampuan menulis ke keranjang itu, tetapi, saya tidak ingin mesin memiliki kemampuan untuk menimpa atau menghapus file apa pun di keranjang itu (termasuk yang saya inginkan untuk menuliskannya).

Jadi pada dasarnya, saya ingin mesin saya hanya dapat menambahkan data ke file log itu, tanpa menimpa atau mengunduhnya.

Apakah ada cara untuk mengkonfigurasi S3 saya agar berfungsi seperti itu? Mungkin ada beberapa kebijakan IAM yang dapat saya lampirkan sehingga akan berfungsi seperti yang saya inginkan?


Anda tidak dapat memodifikasi objek di S3. Bisakah Anda menambahkan file log baru? Itu akan menjadi model yang lebih baik dan akan mendukung banyak klien secara bersamaan.
jarmod

@jarmod Ya, saya memikirkannya, tetapi masalahnya adalah jika penyerang berhasil mengakses server saya, dia akan memiliki kemampuan untuk menghapus file lokal yang disimpan di dalamnya, sebelum dikirim ke bucket S3 (yang katakanlah terjadi di penghujung hari).
Theodore

Anda mungkin juga ingin melihat log CloudWatch. Biarkan ia mengelola kerumitan pengumpulan dan penyimpanan log Anda, berikan fasilitas pencarian, kebijakan penyimpanan, dan memungkinkan Anda untuk menghasilkan peringatan berdasarkan metrik yang dapat Anda sesuaikan untuk log Anda.
jarmod

1
Anda juga dapat melihat Google BigQuery. Anda dapat menggunakannya untuk menyelesaikan masalah Anda.
Daniel777

Jawaban:


133

Sayangnya, Anda tidak bisa.

S3 tidak memiliki operasi "tambahkan". * Setelah sebuah objek diunggah, tidak ada cara untuk mengubahnya; satu-satunya pilihan Anda adalah mengunggah objek baru untuk menggantikannya, yang tidak memenuhi kebutuhan Anda.

*: Ya, saya tahu posting ini berumur beberapa tahun. Ini masih akurat.


Bolehkah saya tahu, dengan menggunakan Multipart Upload dapatkah kita mencapai ini?
Anjali

1
Unggahan Multibagian akan memungkinkan Anda memasukkan data ke S3 tanpa mengunduh objek asli, tetapi tidak memungkinkan Anda untuk menimpa objek asli secara langsung. Lihat misalnya docs.aws.amazon.com/AmazonS3/latest/API/… Anda kemudian dapat menghapus objek lama / mengganti nama yang baru. Namun, ini bukanlah pertanyaan yang ditanyakan.
MikeGM

Menurut saya, menggunakan Unggahan Multi bagian mungkin benar-benar berfungsi. Semua bagian Anda adalah segmen berurutan dari file yang sama. Jika bagian tersebut berhasil diunggah, Anda akhirnya dapat melakukan unggahan tersebut agar dapat membaca file tersebut. Jadi, selama Anda tidak perlu membaca konten file, Anda dapat menambahkan menggunakan unggahan multi-bagian yang sama.
cerebrotecnologico

@ Cerebrotecnologico Saya masih tidak berpikir itu memenuhi persyaratan OP. Tidak ada cara yang saya sadari untuk membatasi pengguna S3 untuk melakukan pengunggahan multi-bagian yang ditambahkan ke suatu objek - jika mereka dapat melakukan pengunggahan multi-bagian, mereka dapat mengunggah konten apa pun yang mereka inginkan.
senjawuff -tidak aktif-

16

Seperti yang dinyatakan oleh jawaban yang diterima, Anda tidak bisa. Solusi terbaik yang saya ketahui adalah menggunakan:

AWS Kinesis Firehose

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

Sampel kode mereka terlihat rumit tetapi sampel Anda bisa sangat sederhana. Anda terus melakukan operasi PUT (atau BATCH PUT) ke aliran pengiriman Kinesis Firehose di aplikasi Anda (menggunakan AWS SDK), dan Anda mengonfigurasi aliran pengiriman Kinesis Firehose untuk mengirim data Anda yang dialirkan ke ember AWS S3 pilihan Anda (di Konsol AWS Kinesis Firehose).

masukkan deskripsi gambar di sini

Ini masih tidak senyaman >>dari baris perintah Linux, karena setelah Anda membuat file di S3, Anda harus berurusan lagi dengan mengunduh, menambahkan, dan mengunggah file baru tetapi Anda hanya perlu melakukannya sekali per kumpulan baris. daripada untuk setiap baris data sehingga Anda tidak perlu khawatir tentang biaya besar karena volume operasi penambahan. Mungkin itu bisa dilakukan tapi saya tidak bisa melihat bagaimana melakukannya dari konsol.


8
Perhatikan bahwa ada waktu maksimal (900 detik sejak pembuatan file) atau ukuran maksimal (ukuran file 128mb) saat melakukan ini - artinya, Kinesis firehose akan menambahkan ke file S3 yang sama hingga mencapai salah satu dari batas tersebut: docs.aws .amazon.com / firehose / latest / dev / create-configure.html
Yaron Budowski

Dapatkah Anda menggunakan satu file S3 sebagai output di Firehose? Kedengarannya agak berantakan harus menggabungkan banyak file dalam bucket S3.
Jón Trausti Arason

1
Sayangnya tidak ada. Saya juga berharap ada solusi yang lebih baik.
Sridhar Sarnobat

Ya itu sangat disayangkan. Saya sangat khawatir tentang kondisi balapan jika saya mengunduh & menambahkan catatan secara manual ke satu objek S3. Saya telah berpikir tentang menambahkan catatan ke SQS dan kemudian menggunakan beberapa logika dengan SNS + Lambda untuk mengumpulkan SQS dan kemudian menulis entri baru ke objek S3.
Jón Trausti Arason

6

Objek di S3 tidak dapat ditambahkan. Anda memiliki 2 solusi dalam kasus ini:

  1. salin semua data S3 ke objek baru, tambahkan konten baru dan tulis kembali ke 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. Pilihan kedua adalah menggunakan Kinesis Firehose. Ini cukup mudah. Anda perlu membuat aliran pengiriman firehose dan menautkan tujuan ke bucket S3. Itu dia!
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
    }); 
}

Bisakah Anda menggunakan satu file S3 sebagai output?
Jón Trausti Arason

1

Seperti yang telah dinyatakan orang lain sebelumnya, objek S3 tidak dapat ditambahkan.
Namun, solusi lain adalah menulis ke log CloudWatch dan kemudian mengekspor log yang Anda inginkan ke S3 . Ini juga akan mencegah penyerang yang mengakses server Anda untuk menghapus dari bucket S3 Anda, karena Lambda tidak memerlukan izin S3 apa pun.


1

Jika ada yang ingin menambahkan data ke objek dengan layanan seperti S3, Alibaba Cloud OSS (Object Storage Service) mendukung ini secara native .

OSS menyediakan upload append (melalui AppendObject API), yang memungkinkan Anda untuk langsung menambahkan konten ke akhir objek. Objek yang diunggah dengan metode ini adalah objek yang dapat ditambahkan, sedangkan objek yang diunggah dengan metode lain adalah objek normal. Data yang ditambahkan langsung dapat dibaca.


-1

Saya memiliki masalah serupa dan inilah yang saya tanyakan

cara Menambahkan data dalam file menggunakan AWS Lambda

Inilah yang saya temukan untuk memecahkan masalah di atas:

Gunakan getObject untuk mengambil dari file yang sudah ada

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

Tulis fungsi untuk ditambahkan ke file

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

Semoga bantuan ini !!


13
writeToS3Fungsi Anda akan menimpa file, bukan menambahkannya.
senja-tidak aktif-

@ senjawuff-tidak aktif- setuju, dan juga menderita kondisi balapan jika dua metode mencoba bekerja pada objek yang sama, tetapi ini tidak terlalu berbeda dari bahasa yang memiliki string atau tipe yang tidak dapat diubah - Anda mensimulasikan penambahan dengan mengembalikan / menimpa dengan objek baru.
fatal_error
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.