2015-06-16 5 views
8

उत्पन्न करता है मैंने एकाधिक थंबनेल आकार बनाने और समानांतर में चलाने के लिए resizing a photo in lambda का अमेज़ॅन उदाहरण अनुकूलित किया है।अमेज़ॅन लैम्ब्डा में, समांतर एसिंक फेंकने में एकाधिक थंबनेल आकारों का आकार बदलना त्रुटि: स्ट्रीम खाली बफर

मेरा कोड कुछ सेकंड में स्थानीय रूप से ठीक से चलता है, लेकिन लैम्ब्डा क्लाउड में, यह समानांतर में नहीं चलता है, पहले थंबनेल आकार का आकार बदलने के बाद त्रुटि को फेंक देता है .. और यदि मैं इसे समानांतर के बजाय धारावाहिक के रूप में स्विच करता हूं क्रमशः चलाने के लिए लगभग 60 सेकंड लगते हैं।

लैम्बडा में समानांतर में आकार बदलने का कारण क्यों होता है क्योंकि धारा खाली बफर त्रुटि उत्पन्न करती है। मैं प्रदर्शन को कैसे बढ़ा सकता हूं ताकि मैं कुछ सेकंड में आकार बना सकूं लेकिन फिर भी प्रोसेसर लागत के मामले में लैम्ब्डा से अच्छा मूल्य और दक्षता प्राप्त हो सकती है?

// dependencies 
var async = require('async'); 
var AWS = require('aws-sdk'); 
var gm = require('gm') 
      .subClass({ imageMagick: true }); // Enable ImageMagick integration. 
var util = require('util'); 

// constants 
var SIZES = [100, 320, 640]; 

// get reference to S3 client 
var s3 = new AWS.S3(); 

exports.handler = function(event, context) { 

    // Read options from the event. 
    console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); 
    var srcBucket = event.Records[0].s3.bucket.name; 
    var srcKey = event.Records[0].s3.object.key; 
    var dstBucket = srcBucket + "-resized"; 

    // Infer the image type. 
    var typeMatch = srcKey.match(/\.([^.]*)$/); 
    if (!typeMatch) { 
     console.error('unable to infer image type for key ' + srcKey); 
     return context.done(); 
    } 
    var imageType = typeMatch[1]; 
    if (imageType != "jpg" && imageType != "png") { 
     console.log('skipping non-image ' + srcKey); 
     return context.done(); 
    } 

    // Sanity check: validate that source and destination are different buckets. 
    if (srcBucket == dstBucket) { 
     console.error("Destination bucket must not match source bucket."); 
     return context.done(); 
    } 

    // Download the image from S3 
    s3.getObject({ 
      Bucket: srcBucket, 
      Key: srcKey 
     }, 
     function(err, response){ 

      if (err) 
       return console.error('unable to download image ' + err); 

      var contentType = response.ContentType; 

      var original = gm(response.Body); 
      original.size(function(err, size){ 

       if(err) 
        return console.error(err); 

       //transform, and upload to a different S3 bucket. 
       async.each(SIZES, 
        function (max_size, callback) { 
         resize_photo(size, max_size, imageType, original, srcKey, dstBucket, contentType, callback); 
        }, 
        function (err) { 
         if (err) { 
          console.error(
           'Unable to resize ' + srcBucket + 
           ' due to an error: ' + err 
          ); 
         } else { 
          console.log(
           'Successfully resized ' + srcBucket 
          ); 
         } 

         context.done(); 
        }); 
      }); 


     }); 



}; 

//wrap up variables into an options object 
var resize_photo = function(size, max_size, imageType, original, srcKey, dstBucket, contentType, done) { 

    var dstKey = max_size + "_" + srcKey; 


    // transform, and upload to a different S3 bucket. 
    async.waterfall([ 

     function transform(next) { 


      // Infer the scaling factor to avoid stretching the image unnaturally. 
      var scalingFactor = Math.min(
       max_size/size.width, 
       max_size/size.height 
      ); 
      var width = scalingFactor * size.width; 
      var height = scalingFactor * size.height; 


      // Transform the image buffer in memory. 
      original.resize(width, height) 
       .toBuffer(imageType, function(err, buffer) { 

        if (err) { 
         next(err); 
        } else { 
         next(null, buffer); 
        } 
       }); 

     }, 
     function upload(data, next) { 
      // Stream the transformed image to a different S3 bucket. 
      s3.putObject({ 
        Bucket: dstBucket, 
        Key: dstKey, 
        Body: data, 
        ContentType: contentType 
       }, 
       next); 
      } 
     ], function (err) { 

      console.log('finished resizing ' + dstBucket + '/' + dstKey); 

      if (err) { 
       console.error(err) 
       ; 
      } else { 
       console.log(
        'Successfully resized ' + dstKey 
       ); 
      } 

      done(err); 
     } 
    ); 
}; 

उत्तर

8

मैं आज रात एक ही मुद्दे में भाग गया।

हालांकि कुछ और हो सकता है जो आप कर सकते हैं, मैंने लैम्ब्डा कार्य की स्मृति को अद्यतन किया और बफर समस्या दूर हो गई।

मैं 2.1 एमबी और 5000x3000 के आसपास छवियों का आकार बदलकर 3 छोटे आकार में कर रहा हूं।

Duration: 11619.86 ms Billed Duration: 11700 ms Memory Size: 1024 MB Max Memory Used: 582 MB

आशा है कि मदद करता है

+0

हाँ आकार बदलने लैम्ब्डा स्मृति के रूप में अच्छी तरह से मेरे लिए यह किया था - मैं जब अमेज़न आर्किटेक्ट पूछा इसके बारे में वे कहते हैं कि हैरान होने के लिए लग रहा था – MonkeyBonkey

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