डेटा को S3 ऑब्जेक्ट में जोड़ें


91

मान लीजिए कि मेरे पास एक मशीन है जिसे मैं S3 बाल्टी पर संग्रहीत एक निश्चित लॉग फ़ाइल में लिखने में सक्षम होना चाहता हूं।

इसलिए, मशीन को उस बाल्टी में लिखने की क्षमता होनी चाहिए, लेकिन, मैं नहीं चाहता कि उस बाल्टी में किसी भी फाइल को अधिलेखित करने या हटाने की क्षमता हो (जिसमें मैं इसे लिखना चाहता हूं)।

इसलिए मूल रूप से, मैं चाहता हूं कि मेरी मशीन केवल उस लॉग फ़ाइल में डेटा संलग्न करने में सक्षम हो, बिना उसे ओवरराइड किए या डाउनलोड किए।

क्या इस तरह से काम करने के लिए मेरे S3 को कॉन्फ़िगर करने का कोई तरीका है? हो सकता है कि कुछ IAM नीति मैं इसे संलग्न कर सकता हूं इसलिए यह काम करेगा जैसे मैं चाहता हूं?


आप S3 में ऑब्जेक्ट्स को संशोधित नहीं कर सकते। क्या आप बस एक नई लॉग फ़ाइल संलग्न कर सकते हैं? यह एक बेहतर मॉडल होगा और कई, एक साथ ग्राहकों का समर्थन करेगा।
जरमोद 21:17

@jarmod हाँ, मैंने इसके बारे में सोचा, लेकिन समस्या यह है कि अगर कोई हमलावर मेरे सर्वर तक पहुंचने में सफल होता है, तो उसके पास S3 बाल्टी को भेजे जाने से पहले उस पर संग्रहीत स्थानीय फ़ाइल को हटाने की क्षमता होगी। दिन के अंत में होता है)।
थियोडोर

आप CloudWatch लॉग पर भी नज़र डालना चाहते हैं। इसे अपने लॉग को इकट्ठा करने और संग्रहीत करने की जटिलता का प्रबंधन करने दें, खोज की सुविधा प्रदान करें, अवधारण नीतियां, और आपको मीट्रिक के आधार पर अलर्ट उत्पन्न करने की अनुमति दें जिसे आप अपने लॉग के लिए अनुकूलित कर सकते हैं।
जरमोद 21:17

1
आप Google BigQuery पर भी नज़र डाल सकते हैं। आप इसका उपयोग अपनी समस्या को हल करने के लिए कर सकते हैं।
डैनियल777

जवाबों:


133

दुर्भाग्य से, आप नहीं कर सकते।

S3 में "परिशिष्ट" ऑपरेशन नहीं है। * एक बार जब कोई वस्तु अपलोड हो जाती है, तो उसे संशोधित करने का कोई तरीका नहीं है; आपका एकमात्र विकल्प इसे बदलने के लिए एक नई वस्तु अपलोड करना है, जो आपकी आवश्यकताओं को पूरा नहीं करता है।

*: हाँ, मुझे पता है कि यह पोस्ट कुछ साल पुरानी है। यह अभी भी सटीक है, हालांकि।


क्या मुझे पता है, Multipart Upload का उपयोग करके हम इसे प्राप्त कर सकते हैं?
अंजली

1
मल्टीपार्ट अपलोड आपको मूल ऑब्जेक्ट को डाउनलोड किए बिना S3 में डेटा प्राप्त करने की अनुमति देगा, लेकिन यह आपको सीधे मूल ऑब्जेक्ट को ओवरराइट करने की अनुमति नहीं देगा। उदाहरण के लिए देखें docs.aws.amazon.com/AmazonS3/latest/API/… फिर आप पुरानी वस्तु को हटा सकते हैं / नया नाम बदल सकते हैं। हालांकि, यह वह नहीं है जो सवाल पूछ रहा है।
माइकजीएम

मुझे लगता है कि मल्टीपार्ट अपलोड का उपयोग वास्तव में काम कर सकता है। आपके सभी भाग एक ही फ़ाइल के अनुक्रमिक खंड हैं। यदि भाग अपलोड होने में सफल होता है, तो आप अंततः फ़ाइल को पढ़ने में सक्षम होने के लिए अपलोड करने के लिए प्रतिबद्ध हो सकते हैं। इसलिए, जब तक आपको फ़ाइल की सामग्री को पढ़ने की आवश्यकता नहीं है, तब तक आप उसी मल्टीपार्ट अपलोड का उपयोग करने के लिए संलग्न हो सकते हैं।
cerebrotecnologico

@ cerebrotecnologico मुझे अभी भी नहीं लगता कि यह ओपी की आवश्यकताओं को पूरा करता है। ऐसा कोई तरीका नहीं है जिससे मैं किसी S3 उपयोगकर्ता को मल्टीपार्ट अपलोड करने के लिए प्रतिबंधित कर सकूं, जो किसी ऑब्जेक्ट के लिए अपलोड होते हैं - यदि वे मल्टीपार्ट अपलोड कर सकते हैं, तो वे अपनी इच्छानुसार कोई भी सामग्री अपलोड कर सकते हैं।
डस्कवफ-एक्टिव-

16

जैसा कि स्वीकृत उत्तर बताता है, आप नहीं कर सकते। सबसे अच्छा समाधान जो मुझे पता है कि उपयोग करना है:

एडब्ल्यूएस किनेसिस फायरहोज

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

उनका कोड नमूना जटिल दिखता है लेकिन आपका वास्तव में सरल हो सकता है। आप अपने एप्लिकेशन (AWS SDK का उपयोग करके) में Kinesis Firehose डिलीवरी स्ट्रीम पर PUT (या BATCH PUT) ऑपरेशन करते रहते हैं, और आप अपनी स्ट्रीम किए गए डेटा को अपनी पसंद के AWS S3 बाल्टी में भेजने के लिए Kinesis Firehose डिलीवरी स्ट्रीम को कॉन्फ़िगर करते हैं (में AWS Kinesis Firehose कंसोल)।

यहाँ छवि विवरण दर्ज करें

यह अभी भी >>लिनक्स कमांड लाइन से उतना सुविधाजनक नहीं है , क्योंकि एक बार जब आप एस 3 पर एक फ़ाइल बनाते हैं, तो आपको फिर से नई फ़ाइल को डाउनलोड करने, संलग्न करने और अपलोड करने से निपटना होगा, लेकिन आपको केवल एक बार लाइनों के बैच के अनुसार करना होगा डेटा की प्रत्येक पंक्ति की तुलना में इसलिए आपको परिशिष्ट परिचालनों की मात्रा के कारण भारी शुल्क के बारे में चिंता करने की आवश्यकता नहीं है। शायद यह किया जा सकता है, लेकिन मैं यह नहीं देख सकता कि इसे कंसोल से कैसे किया जाए।


8
ध्यान दें कि ऐसा करने पर अधिकतम समय (फ़ाइल निर्माण के बाद से 900 सेकंड) या अधिकतम आकार (128mb फ़ाइल आकार) है - अर्थ, किनेसिस फ़ायरहोज़
Yaron Budowski

क्या आप फायरहोज़ पर आउटपुट के रूप में एकल S3 फ़ाइल का उपयोग कर सकते हैं? यह एक S3 बाल्टी में कई फ़ाइलों को मर्ज करने के लिए थोड़ा गड़बड़ लगता है।
जोन ट्रॉस्टी एरसन

1
दुर्भाग्यवश नहीं। मैं भी चाहता हूं कि इसका बेहतर समाधान हो।
श्रीधर सरनोबत

हाँ यह दुर्भाग्यपूर्ण है। मैं ज्यादातर दौड़ की स्थिति के बारे में चिंतित हूं अगर मैं मैन्युअल रूप से एक ही S3 ऑब्जेक्ट पर रिकॉर्ड डाउनलोड और संलग्न करूं। मैं SQS में रिकॉर्ड जोड़ने के बारे में सोच रहा हूँ और फिर SQ + लैम्ब्डा के साथ कुछ तर्क का उपयोग करके SQS का चुनाव करता हूँ और फिर S3 ऑब्जेक्ट में नई प्रविष्टियाँ लिखता हूँ।
जॉन ट्रॉस्टी अरसन

6

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 का उपयोग करना है। यह काफी सीधा है। आपको अपनी फ़ायरहोज़ डिलीवरी स्ट्रीम बनाने और गंतव्य को 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 फ़ाइल का उपयोग कर सकते हैं?
जोन ट्रॉस्टी एरसन

1

जैसा कि अन्य लोगों ने पहले कहा है, S3 ऑब्जेक्ट एपेंडेड-सक्षम नहीं हैं।
हालाँकि, क्लाउडवॉच लॉग्स के लिए एक और समाधान लिखना होगा और फिर उन लॉग्स को निर्यात करें जिन्हें आप S3 में चाहते हैं । यह किसी भी हमलावर को भी रोकता है जो आपके सर्वर को आपकी S3 बाल्टी से हटाने से रोकते हैं, क्योंकि लैम्बडा को किसी S3 अनुमतियों की आवश्यकता नहीं होगी।


1

यदि कोई किसी S3 जैसी सेवा के साथ ऑब्जेक्ट को डेटा जोड़ना चाहता है, तो अलीबाबा क्लाउड OSS (ऑब्जेक्ट स्टोरेज सर्विस) मूल रूप से समर्थन करता है

OSS एपेंड अपलोड (AppendObject एपीआई के माध्यम से) प्रदान करता है, जो आपको किसी वस्तु के अंत में सीधे सामग्री को जोड़ने की अनुमति देता है। इस पद्धति का उपयोग करके अपलोड की जाने वाली वस्तुएं वस्‍तुएं हैं, जबकि अन्‍य विधियों का उपयोग करके अपलोड की गई वस्‍तुएं सामान्‍य वस्‍तुएं हैं। जोड़ा गया डेटा तुरन्त पठनीय है।


-1

मेरे पास भी ऐसा ही मुद्दा था और मैंने यही पूछा था

AWS लैम्ब्डा का उपयोग करके फ़ाइल में डेटा कैसे जोड़ें

उपरोक्त समस्या को हल करने के लिए मैं यहाँ आया हूँ:

मौजूदा फ़ाइल से पुनर्प्राप्त करने के लिए 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- निष्क्रिय- सहमत, और यह भी दौड़ की स्थिति से ग्रस्त है अगर दो विधियाँ एक ही वस्तु पर काम करने की कोशिश करती हैं, लेकिन यह वास्तव में उन भाषाओं से अलग नहीं है जिनके पास अपरिवर्तनीय तार या प्रकार हैं - आप एक परिशिष्ट को वापस करके या ओवरराइटिंग के साथ अनुकरण करते हैं एक नई वस्तु।
घातक_रोर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.