2016-12-19 65 views
0

我在AWS Lambda with Node.js中遇到超時問題,默認超時時間爲300 secs如何忽略AWS Lambda超時限制300秒以執行長時間?

我想從S3 bucket下載zipsize>300MB並解壓後,上傳到同一個存儲桶中的臨時文件夾中。

但是由於大量數據,我無法在時間間隔內完成此操作。

我可以去EBS,但想要得到任何最接近的解決方案,可以使用Lambda功能。

如果我能得到一個相關的建議來完成這個任務,這將是非常好的。

這裏是我用Lambda函數編寫的東西。

exports.handler = (event, context, callback) => { 
    console.log('Received event for big file:', JSON.stringify(event, null, 2)); 

    // Get the object from the event and show its content type 
    const bucket = event.Records[0].s3.bucket.name; 
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); 
    const params = { 
     Bucket: bucket, 
     Key: key, 
    }; 
    s3.getObject(params, (err, data) => { 
     if (err) { 
      console.log('Error', err); 
      const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; 
      console.log(message); 
      callback(message); 
     } else { 
      console.log('Started to save buffers....'); 
      JSZip.loadAsync(data.Body).then(function(zip) { 
       console.log('Started to extract files.....'); 
       async.eachSeries(zip.files, function(item, cbk1) { 
        if (!item.dir) { 
         async.waterfall([function(cbk) { 
          zip.file(item.name).async("text").then(function(content) { 
           cbk(null, content) 
          }) 
         }], function(err, content) { 
          s3.putObject({ 
           Bucket: bucket, 
           Key: 'bigtemp/' + item.name.replace(/^.*[\\\/]/, ''), 
           Body: content 
          }, function(err, result) { 
           if(result && result.ETag){ 
           console.log('uploaded file: ', result.ETag); 
           } 
           console.log('Error ', err); 
           cbk1(); 
          }); 
         }) 
        } else { 
         cbk1(); 
        } 
       }); 
      }); 
      callback(null, data.ContentType); 
     } 
    }); 
}; 

謝謝

+1

您是否嘗試增加Lambda函數的內存分配?另外,你爲什麼使用'async.eachSeries'來強制序列化,而不是使用'async.each',它可以並行處理'zip.files'中的每個文件。您可以嘗試的另一件事是使用流:'s3.getObject(params).createReadStream()。pipe(unzip.Parse())。on('entry',...)'。 'S3。putObject()'也會接受一個可讀的流作爲'Body'的值。 – idbehold

+0

感謝您的寶貴意見。我會更新我的代碼 – abdulbarik

回答

3

的300秒超時由AWS徵收,雖然它可以改變它的未來(這已經發生過一次 - 那是以前60秒)這今天不會幫助你。單獨使用Lambda並不適用於長時間運行的流程。

方案1:通過在泊塢

解決方案模擬AWS LAMBDA遷移到ECS存在端口將拉姆達功能ECS,而無需通過在泊塢窗容器模仿lambda來重寫你的函數。您可以使用docker-lambdanode-docker-lambda來模擬docker中的lambda,然後您只需通過runTask傳遞事件。

如果您最終想改變想維護您的lambda函數的想法,另一個示例使用lambda作爲事件接收器,並將大部分工作轉移到ECS中。

一些示例實現:

選項2:AWS步驟功能

如果超時不是瓶子口上,你可能能夠把它們分割AWS Step Functions,有效地將一個拉姆達成許多單個特定操作。因此,一個函數將調用S3 getObject,另一個函數將處理壓縮,另一個調用S3 putObject等,以根據需要解決超時問題。我懷疑事實並非如此,但值得一提。

+0

謝謝@Anthony,我會跟你的建議。 – abdulbarik