ผนวกข้อมูลเข้ากับอ็อบเจ็กต์ S3


96

สมมติว่าฉันมีเครื่องที่ฉันต้องการเขียนลงในไฟล์บันทึกบางอย่างที่เก็บไว้ในที่เก็บข้อมูล S3

ดังนั้นเครื่องจำเป็นต้องมีความสามารถในการเขียนลงในที่เก็บข้อมูลนั้น แต่ฉันไม่ต้องการให้เครื่องมีความสามารถในการเขียนทับหรือลบไฟล์ใด ๆ ในที่เก็บข้อมูลนั้น (รวมถึงไฟล์ที่ฉันต้องการให้เขียนด้วย)

โดยพื้นฐานแล้วฉันต้องการให้เครื่องของฉันสามารถต่อท้ายข้อมูลลงในไฟล์บันทึกนั้นได้โดยไม่ต้องลบล้างหรือดาวน์โหลด

มีวิธีกำหนดค่า S3 ของฉันให้ทำงานแบบนั้นหรือไม่? อาจมีนโยบาย IAM บางอย่างที่ฉันสามารถแนบได้เพื่อให้ทำงานได้อย่างที่ต้องการ


คุณไม่สามารถแก้ไขวัตถุใน S3 คุณช่วยต่อท้ายไฟล์บันทึกใหม่ได้ไหม นั่นจะเป็นโมเดลที่ดีกว่าและรองรับไคลเอนต์หลาย ๆ ตัวพร้อมกัน
jarmod

@jarmod ใช่ฉันคิดเกี่ยวกับเรื่องนั้น แต่ปัญหาคือถ้าผู้โจมตีประสบความสำเร็จในการเข้าถึงเซิร์ฟเวอร์ของฉันเขาจะสามารถลบไฟล์ในเครื่องที่จัดเก็บไว้ก่อนที่จะถูกส่งไปยังที่เก็บ S3 (ซึ่งสมมติว่า เกิดขึ้นในตอนท้ายของวัน)
Theodore

คุณอาจต้องการดูบันทึก CloudWatch ให้จัดการความซับซ้อนในการรวบรวมและจัดเก็บบันทึกของคุณจัดหาสิ่งอำนวยความสะดวกในการค้นหานโยบายการเก็บรักษาและช่วยให้คุณสร้างการแจ้งเตือนตามเมตริกที่คุณสามารถปรับแต่งสำหรับบันทึกของคุณได้
jarmod

1
คุณอาจดู Google BigQuery คุณสามารถใช้เพื่อแก้ปัญหาของคุณ
Daniel777

คำตอบ:


137

น่าเสียดายที่คุณทำไม่ได้

S3 ไม่มีการดำเนินการ "ผนวก" *เมื่ออัปโหลดวัตถุแล้วจะไม่มีวิธีใดที่จะแก้ไขได้ ทางเลือกเดียวของคุณคืออัปโหลดออบเจ็กต์ใหม่เพื่อแทนที่ซึ่งไม่ตรงตามความต้องการของคุณ

*: ใช่ฉันรู้ว่าโพสต์นี้มีอายุสองสามปี มันยังคงถูกต้องแม้ว่า


ฉันขอทราบได้ไหมว่าการอัปโหลดแบบหลายส่วนจะทำให้เราบรรลุเป้าหมายนี้ได้หรือไม่
Anjali

2
การอัปโหลดหลายส่วนจะช่วยให้คุณได้รับข้อมูลใน S3 โดยไม่ต้องดาวน์โหลดวัตถุดั้งเดิม แต่จะไม่อนุญาตให้คุณเขียนทับวัตถุดั้งเดิมโดยตรง ดูเช่นdocs.aws.amazon.com/AmazonS3/latest/API/… จากนั้นคุณสามารถลบวัตถุเก่า / เปลี่ยนชื่อใหม่ได้ อย่างไรก็ตามนี่ไม่ใช่สิ่งที่คำถามถาม
MikeGM

ฉันคิดว่าการใช้ Multipart Upload อาจใช้งานได้จริง ทุกส่วนของคุณเป็นเซ็กเมนต์ตามลำดับของไฟล์เดียวกัน หากอัปโหลดส่วนนั้นสำเร็จในที่สุดคุณสามารถยืนยันการอัปโหลดเพื่อให้สามารถอ่านไฟล์ได้ ดังนั้นตราบใดที่คุณไม่จำเป็นต้องอ่านเนื้อหาของไฟล์คุณสามารถต่อท้ายโดยใช้การอัปโหลดหลายส่วนเดียวกันได้
cerebrotecnologico

@cerebrotecnologico ฉันยังไม่คิดว่ามันตรงตามข้อกำหนดของ OP ไม่มีวิธีใดที่ฉันทราบถึงการ จำกัด ผู้ใช้ S3 ในการอัปโหลดแบบหลายส่วนซึ่งผนวกเข้ากับออบเจ็กต์หากพวกเขาสามารถทำการอัปโหลดแบบหลายส่วนได้พวกเขาสามารถอัปโหลดเนื้อหาที่ต้องการได้
duskwuff -inactive-

19

ในฐานะที่เป็นคำตอบที่ยอมรับคุณไม่สามารถทำได้ ทางออกที่ดีที่สุดที่ฉันทราบคือใช้:

AWS Kinesis Firehose

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

ตัวอย่างโค้ดของพวกเขาดูซับซ้อน แต่ของคุณนั้นง่ายมาก คุณยังคงดำเนินการ PUT (หรือ BATCH PUT) ไปยังสตรีมการส่ง Kinesis Firehose ในแอปพลิเคชันของคุณ (โดยใช้ AWS SDK) และคุณกำหนดค่าสตรีมการส่ง Kinesis Firehose เพื่อส่งข้อมูลที่สตรีมของคุณไปยังที่เก็บข้อมูล AWS S3 ที่คุณเลือก (ในส่วน คอนโซล AWS Kinesis Firehose)

ป้อนคำอธิบายภาพที่นี่

มันยังไม่สะดวกเท่า>>จากบรรทัดคำสั่ง Linux เพราะเมื่อคุณสร้างไฟล์บน S3 แล้วคุณจะต้องจัดการกับการดาวน์โหลดต่อท้ายและอัปโหลดไฟล์ใหม่อีกครั้ง แต่คุณต้องทำเพียงครั้งเดียวต่อชุดบรรทัดแทน มากกว่าข้อมูลทุกบรรทัดดังนั้นคุณจึงไม่ต้องกังวลกับค่าใช้จ่ายจำนวนมากเนื่องจากปริมาณการดำเนินการต่อท้าย อาจจะทำได้ แต่ไม่เห็นวิธีทำจากคอนโซล


8
โปรดทราบว่ามีเวลาสูงสุด (900 วินาทีนับตั้งแต่สร้างไฟล์) หรือขนาดสูงสุด (ขนาดไฟล์ 128mb) ในการทำสิ่งนี้ - หมายความว่า Kinesis firehose จะต่อท้ายไฟล์ S3 เดียวกันจนกว่าจะถึงขีด จำกัด อย่างใดอย่างหนึ่ง: docs.aws .amazon.com / firehose / latest / dev / create-configure.html
Yaron Budowski

คุณสามารถใช้ไฟล์ S3 ไฟล์เดียวเป็นเอาต์พุตบน Firehose ได้หรือไม่? ฟังดูยุ่งยากเล็กน้อยที่ต้องรวมไฟล์หลาย ๆ ไฟล์ในถัง S3
Jón Trausti Arason

1
น่าเสียดายที่ไม่มี ฉันก็หวังว่าจะมีทางออกที่ดีกว่านี้
Sridhar Sarnobat

ใช่มันโชคร้าย ส่วนใหญ่ฉันกังวลเกี่ยวกับสภาพการแข่งขันหากฉันดาวน์โหลดและต่อท้ายระเบียนด้วยตนเองในวัตถุ S3 เดียว ฉันคิดเกี่ยวกับการเพิ่มระเบียนลงใน SQS แล้วใช้ตรรกะบางอย่างกับ SNS + Lambda เพื่อสำรวจ SQS แล้วเขียนรายการใหม่ไปยังวัตถุ S3
Jón Trausti Arason

7

อ็อบเจ็กต์บน 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. ตัวเลือกที่สองคือใช้ 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
    }); 
}

คุณสามารถใช้ไฟล์ S3 ไฟล์เดียวเป็นเอาต์พุตได้หรือไม่?
Jón Trausti Arason

2

ในกรณีที่ทุกคนต้องการที่จะผนวกข้อมูลไปยังวัตถุที่มี S3 เหมือนบริการอาลีบาบาเมฆ OSS (Object Storage Service) นี้สนับสนุนโดยกำเนิด

OSS ให้การอัปโหลดต่อท้าย (ผ่าน AppendObject API) ซึ่งช่วยให้คุณสามารถผนวกเนื้อหาที่ส่วนท้ายของออบเจ็กต์ได้โดยตรง วัตถุที่อัปโหลดโดยใช้วิธีนี้เป็นวัตถุที่ต่อท้ายได้ในขณะที่วัตถุที่อัปโหลดโดยใช้วิธีการอื่นเป็นวัตถุปกติ ข้อมูลต่อท้ายสามารถอ่านได้ทันที


1

ตามที่คนอื่น ๆ ได้ระบุไว้ก่อนหน้านี้อ็อบเจ็กต์ S3 ไม่สามารถต่อท้ายได้
อย่างไรก็ตามวิธีอื่นจะเขียนออกไปบันทึก CloudWatch แล้วส่งออกบันทึกที่คุณต้องการ S3 นอกจากนี้ยังช่วยป้องกันไม่ให้ผู้โจมตีที่เข้าถึงเซิร์ฟเวอร์ของคุณลบออกจากที่เก็บข้อมูล S3 ของคุณเนื่องจาก Lambda ไม่ต้องการสิทธิ์ S3 ใด ๆ


-1

ฉันมีปัญหาที่คล้ายกันและนี่คือสิ่งที่ฉันถาม

วิธีผนวกข้อมูลในไฟล์โดยใช้ 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');
     });
}

หวังว่านี่จะช่วยได้ !!


13
writeToS3ฟังก์ชันของคุณจะเขียนทับไฟล์ไม่ใช่ต่อท้าย
duskwuff -inactive-

@duskwuff-inactive- ตกลงและยังทนทุกข์ทรมานจากเงื่อนไขการแข่งขันหากสองวิธีพยายามทำงานบนวัตถุเดียวกัน แต่สิ่งนี้ไม่แตกต่างจากภาษาที่มีสตริงหรือประเภทที่ไม่เปลี่ยนรูป - คุณจำลองการผนวกโดยการส่งคืน / เขียนทับด้วย วัตถุใหม่
fatal_error
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.