我是通过此代码将文件从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,或者没有结果,具体取决于数量 时间已经过去了。
答案 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分钟左右应该有助于避免执行超时异常。