2015-02-22 7 views
5

मेरी कंपनी S3 पर बड़ी संग्रह फ़ाइलों को अपलोड कर रही है, और अब उन्हें एस 3 पर अनजिप किया जाना चाहता है। मैंने अनजिप के आधार पर एक लैम्ब्डा फ़ंक्शन लिखा, जो xxx-zip बाल्टी में फ़ाइल के आगमन से ट्रिगर हुआ, जो एस 3 से ज़िप फ़ाइल स्ट्रीम करता है, स्ट्रीम को अनजिप करता है, और फिर व्यक्तिगत फ़ाइलों को xxx-data बाल्टी में स्ट्रीम करता है।एस 3 में अभिलेखागार को अनजिप करने के लिए लैम्ब्डा फ़ंक्शंस का उपयोग करना वास्तव में sloooooow

यह काम करता है, लेकिन मुझे लगता है कि यह अपेक्षा से धीमा है - यहां तक ​​कि एक टेस्ट फ़ाइल पर, 500k के आकार का ज़िप आकार और लगभग 500 फाइलें रखकर, यह 60 सेकेंड टाइमआउट सेट के साथ समाप्त हो रहा है। क्या यह सही लगता है? नोड के साथ चलने वाले मेरे स्थानीय सिस्टम पर यह इससे तेज है। ऐसा लगता है कि चूंकि अमेज़ॅन के क्लाउड विलंबता के अंदर फ़ाइलों को स्थानांतरित किया जा रहा है, क्योंकि फाइलों को स्ट्रीम किया जा रहा है, इसलिए वास्तविक समय लिया जाना चाहिए, जो स्ट्रीम को अनजिप करने के लिए होता है।

क्या कोई अंतर्निहित कारण है कि यह काम नहीं करेगा, या मेरे कोड में ऐसा कुछ है जो इसे धीमा कर रहा है? यह पहली बार है जब मैंने node.js के साथ काम किया है, इसलिए मैं कुछ बुरी तरह से कर सकता था। या ऐसा करने का एक बेहतर तरीका है कि मैं Google के साथ नहीं ढूंढ पाया?

यहाँ कोड की एक रूपरेखा

var aws = require('aws-sdk'); 
var s3 = new aws.S3({apiVersion: '2006-03-01'}); 
var unzip = require('unzip'); 
var stream = require('stream'); 
var util = require("util"); 
var fs = require('fs'); 

exports.handler = function(event, context) { 
    var zipfile = event.Records[0].s3.object.key; 
    s3.getObject({Bucket:SOURCE_BUCKET, Key:zipfile}, 
    function(err, data) { 
     var errors = 0; 
     var total = 0; 
     var successful = 0; 
     var active = 0; 
     if (err) { 
      console.log('error: ' + err); 
     } 
     else { 
      console.log('Received zip file ' + zipfile); 
      new BufferStream(data.Body) 
      .pipe(unzip.Parse()).on('entry', function(entry) { 
       total++; 
       var filename = entry.path; 
       var in_process = ' (' + ++active + ' in process)'; 
       console.log('extracting ' + entry.type + ' ' + filename + in_process); 
       s3.upload({Bucket:DEST_BUCKET, Key: filename, Body: entry}, {}, 
       function(err, data) { 
        var remaining = ' (' + --active + ' remaining)'; 
        if (err) { 
         // if for any reason the file is not read discard it 
         errors++ 
         console.log('Error pushing ' + filename + ' to S3' + remaining + ': ' + err); 
         entry.autodrain(); 
        } 
        else { 
         successful++; 
         console.log('successfully wrote ' + filename + ' to S3' + remaining); 
        } 
       }); 
      }); 
      console.log('Completed, ' + total + ' files processed, ' + successful + ' written to S3, ' + errors + ' failed'); 
      context.done(null, ''); 
     } 
    }); 
} 

उत्तर

3

मुझे लगता है कि unzip मॉड्यूल का उपयोग कर रहे एक जावास्क्रिप्ट कार्यान्वयन है (BufferStream एक वर्ग मैंने लिखा लपेटता है कि बफर एक readStream में s3.getObject() द्वारा दिया है) यह है कि आपको ज़िप फ़ाइलों को अनजिप करने की अनुमति देता है - जो बहुत धीमी है।

मैं फ़ाइलों को फ़ाइलों को संपीड़ित करने के लिए gzip का उपयोग करने और आंतरिक zlib लाइब्रेरी का उपयोग करके सी संकलित किया गया है और इसे बेहतर प्रदर्शन प्रदान करना चाहिए।

यदि आप ज़िप के साथ चिपकने का विकल्प चुनते हैं, तो आप अमेज़ॅन समर्थन से संपर्क कर सकते हैं और अपने लैम्ब्डा फ़ंक्शन पर 60 सेकंड की सीमा बढ़ाने के लिए कह सकते हैं।

+0

सुझाव के लिए धन्यवाद। मैं समय की तुलना करने के लिए zlib के साथ ऐसा करने की कोशिश कर रहा हूं, लेकिन S3 (http://stackoverflow.com/questions/28688490/untarring-files-to-s3-fails-not-sure- क्यों) पर अपलोड करने में कोई समस्या नहीं आई – russell

+3

अधिक माप के बाद मैंने पाया कि यह फाइलों का आकार है, न कि संख्या, जो समस्या का कारण बनती है। यदि संग्रह में 5 एमबी टेक्स्ट फ़ाइल है जो अकेले ही अधिकतर समय लेती है। तो ऐसा लगता है कि ऐसा करने का यह सही तरीका नहीं है। मैं इसके बजाय एसक्यूएस से ईसी 2 मतदान पर लिखने जा रहा हूं। – russell

संबंधित मुद्दे