附加到S3 ObjectCreated事件的AWS Lambda返回“NoSuchKey:指定的密钥不存在:

时间:2016-08-17 08:56:31

标签: amazon-s3 aws-lambda aws-sdk amazon-javascript-sdk

我是通过此代码将文件从Android设备上传到S3存储桶

TransferUtility trasnferManager = new TransferUtility(s3, context);
trasnferManager.upload(..,..,..);

之后我将一个lambda触发器附加到S3:ObjectCreated事件。

当执行lambda时,我试图通过 S3.getObject()函数获取文件。不幸的是,有时我收到“ NoSuchKey:指定的密钥不存在:”错误。在此之后,lambda重试几次并成功获取文件并继续执行。

在我看来lambda函数是在S3中的文件可以使用之前执行的吗?但这不应该在设计上发生。 S3上的文件上传完成后,应触发触发器。

根据 2015年8月4日的公告

  

所有区域中的Amazon S3存储桶提供读写后一致性   用于新对象的PUTS以及覆盖PUTS的最终一致性   和DELETES。

     

Read-after-write 一致性允许您在Amazon S3中创建后立即检索对象。

但在此之前:

  

美国标准(重命名为美国东部(弗吉尼亚北部))以外的所有地区均支持写入后读取   上传到Amazon S3的新对象的一致性。

我的广告位于美国东部(弗吉尼亚北部)区域,并且是在 2015年8月4日之前创建的。我不知道这可能是问题...

编辑: 20.10.2016

根据documentaion - EVENTUALLY CONSISTENT READ 操作可能会返回无结果,即使已完成两项或多项 WRITE 操作在它之前。

在此示例中,W1(写入1)和W2(写入2)都在R1(读取1)和R2开始之前完成 (阅读2)。对于一致读取,R1和R2都返回color = ruby​​。最终是一致的 读取,R1和R2可能会返回color = red,color = ruby​​,或者没有结果,具体取决于数量 时间已经过去了。

Consistent example

2 个答案:

答案 0 :(得分:2)

有时,当文件很大时,它们会使用多部分上传进行上传,并在文件完全上传之前向lambda发送触发器。据推测,它与触发Lambda函数的事件有关。在lambda函数的事件字段中,请确保将put和完成的多部分上传添加到事件中。

答案 1 :(得分:0)

为了防止此问题,可以使用S3 SDK服务器。收到通知后,我们可以确保对象实际存在。例如,对于AWS JavaScript SDK,您可以使用以下代码段:

s3.waitFor("objectExists", {
    Bucket: "<bucket-name>",
    Key: "<object-key>"
}, callback);

请注意,waitFor会增加Lambda的执行时间,这意味着您需要延长超时时间。根据文档,检查将每5秒进行一次,最多20次。因此,将超时设置为大约1分钟左右应该有助于避免执行超时异常。

链接到文档:AWS JavaScript SDK S3 Class