简体   繁体   English

AWS Lambda函数和S3-仅在对象更改时才在S3中更改对象的元数据

[英]AWS Lambda function and S3 - change metadata on an object in S3 only if the object changed

I have a function in Lambda that should add Metadata headers to an object on s3 only if the object changed. 我在Lambda中有一个函数,仅当对象更改时,该函数才应将s3的元数据标头添加到对象。

 ContentType: 'application/javascript' CacheControl: 'max-age=600' 

But it turns out that Lambda check the bucket around 100 times in a sec and not only if the object changed, and its cost a lot. 但是事实证明,Lambda可以在每秒内大约100次检查存储桶,这不仅是因为对象发生了变化,而且还花费了很多成本。

Access log on S3: 访问S3上的日志:

 b6234e2652b93344f7 aa [02/Mar/2016:11:00:55 +0000] 54.0.0.209 arn:aws:sts::718436:assumed-role/lambda_s3_exec_role/awslambda_642_201609 805 REST.COPY.OBJECT /local.js "PUT /local.js HTTP/1.1" 200 - 234 4404 50 24 "-" "aws-sdk-nodejs/2.2.32 linux/v0.10.36" - b6234ee5f9cf0344f7 aa [02/Mar/2016:11:00:55 +0000] 54.0.0.209 arn:aws:sts::71836:assumed-role/lambda_s3_exec_role/awslambda_642_209 890005 REST.COPY.OBJECT_GET local.js - 200 - - 4404 - - - - - 

Function: 功能:

 console.log('Loading function'); var aws = require('aws-sdk'); var s3 = new aws.S3({ apiVersion: '2006-03-01' }); exports.handler = function(event, context) { //console.log('Received event:', JSON.stringify(event, null, 2)); // Get the object from the event and show its content type var bucket = event.Records[0].s3.bucket.name; var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\\+/g, ' ')); var params = { Bucket: bucket, Key: key, CopySource: encodeURIComponent(bucket+"/"+key), ContentType: 'application/javascript', CacheControl: 'max-age=600', "Metadata":{ }, MetadataDirective: 'REPLACE' }; //s3.getObject(params, function(err, data) { s3.copyObject(params, function(err, data) { if (err) { console.log(err); var 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); context.fail(message); } else { console.log('CONTENT TYPE:', data.ContentType); context.succeed(data.ContentType); } }); }; 

What I need to changed in order the function will work only if the object changed in s3 ? 我需要更改什么才能使该功能仅在s3中更改了对象后才能起作用?

Thanks in advanced ! 提前致谢 !

You created an infinite loop bug for yourself! 您为自己创建了一个无限循环错误! The Lambda function is triggered when the object is changed, and by changing the metadata and using copyObject you change the object and thus load the Lambda function again. 更改对象时会触发Lambda函数,通过更改元数据并使用copyObject可以更改对象,从而再次加载Lambda函数。 You immediately hit the 100 concurrent requests Lambda limit which is there to make sure you don't have to pay a million euros now because you wrote an infinite loop. 您立即达到了100个并发请求Lambda限制,以确保您现在不必支付一百万欧元,因为您编写了一个无限循环。

To circumvent this, you need to rethink your architecture. 为了避免这种情况,您需要重新考虑您的体系结构。 There are multiple options, but the easiest is this one I think: 有多种选择,但我认为最简单的选择是:

In your Lambda code, do s3.getObject first and check if the headers you want to change are already there. 在您的Lambda代码中,首先执行s3.getObject并检查您要更改的标头是否已经存在。 If so, close the Lambda function. 如果是这样,请关闭Lambda函数。 This way you only execute the Lambda function twice per edit. 这样,您每次编辑仅执行Lambda函数两次。 Not 100% ideal, but good enough for practical purposes imo. 不是100%理想,但足以满足imo的实际用途。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM