S3事件触发器是否可扩展?

时间:2017-11-06 21:42:55

标签: amazon-web-services amazon-s3 aws-lambda

将3K对象(文件)加载到S3。有一个事件触发器加载到该S3存储桶的每个文件。

Lambda仅接收大约300个对象的事件触发器。如果我重试(从S3返回并将其放回S3),它会为另外400个对象生成事件,其余的事件甚至无法达到lambda。

我在这里缺少什么,如何缩放任何数量的对象?

var async = require('async');                                                                                                                                                                                
var aws = require('aws-sdk');                                                                                                                                                                                
var s3 = new aws.S3();                                                                                                                                                                                       
var kinesis = new aws.Kinesis();                                                                                                                                                                             
var sns = new aws.SNS();                                                                                                                                                                                     
var config = require('./config.js');                                                                                                                                                                         


var logError = function(errormsg) {                                                                                                                                                                          
    sns.publish({                                                                                                                                                                                            
        TopicArn: config.TopicArn,                                                                                                                                                                           
        Message: errormsg                                                                                                                                                                                    
    }, function(err, data) {                                                                                                                                                                                 
        if (err) {                                                                                                                                                                                           
            console.log(errormsg);                                                                                                                                                                           
        }                                                                                                                                                                                                    
    });                                                                                                                                                                                                      
};                                                                                                                                                                                                           


exports.handler = function(event, context, callback) {                                                                                                                                                       

    var readS3andSendtoKinesis = function(record, index, cb) {                                                                                                                                               
        var params = {                                                                                                                                                                                       
            Bucket: record.s3.bucket.name,                                                                                                                                                                   
            Key: record.s3.object.key                                                                                                                                                                        
        }; 
        console.log('Received File: ' +  record.s3.object.key);                                                                                                                                                                                                 
        s3.getObject(params, function(err, data) {                                                                                                                                                           
            if (!err) {                                                                                                                                                                                      
                var kinesisParams = {                                                                                                                                                                        
                    Data: data.Body.toString('utf8'),                                                                                                                                                        
                    PartitionKey: config.PartitionKey,                                                                                                                                                       
                    StreamName: config.StreamName                                                                                                                                                            
                };                                                                                                                                                                                           
                kinesis.putRecord(kinesisParams, function(err, data) {                                                                                                                                       
                    if (err) {                                                                                                                                                                               
                        // Handle Kinesis Failures                                                                                                                                                           
                        logError(JSON.stringify(err, null, 2));                                                                                                                                              
                    }                                                                                                                                                                                        
                    cb(null, 'done');                                                                                                                                                                        
                });                                                                                                                                                                                          
            } else {                                                                                                                                                                                         
                // Handle S3 Failures                                                                                                                                                                        
                logError(JSON.stringify(err, null, 2));                                                                                                                                                      
                cb(null, 'done');                                                                                                                                                                            
            }                                                                                                                                                                                                
        });                                                                                                                                                                                                  
    };                                                                                                                                                                                                       

    async.eachOfLimit(event.Records, 1, readS3andSendtoKinesis, function(err) {                                                                                                                              
        callback(null, 'Done');                                                                                                                                                                              
    });                                                                                                                                                                                                      
}; 

由于每个人都建议查看cloudwatch,在此处分享相关lambda的cloudwatch指标,

enter image description here

2 个答案:

答案 0 :(得分:1)

我们发现根本原因似乎在资源的另一端失败了。 S3触发器发生并无法扩展到它收到的巨大触发器。

要解决,

  

尽快返回S3 Lambda Trigger,延迟会导致问题。

如果你花费太多时间来处理触发器内部的业务逻辑,在我们的例子中,我们从S3读取并写入流。相反,我们只是编写了S3的位置,并在接收端从S3读取。

希望它有所帮助。

答案 1 :(得分:0)

AWS Lambda具有限制配置,可避免失控情况。

对于S3,Lambda调用也依赖于permissions,因此您应该检查这些权限。

由于S3不是基于流的源,因此您可能会看到同步方案,其中throttling达到限制且S3未重试。检查lambdas中的限制和错误429。