11

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

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

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

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

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

根据2015年8月4日的公告:

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

写后读一致性允许您在 Amazon S3 中创建对象后立即检索对象。

但在此之前:

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

我的存储桶位于美国东部(弗吉尼亚北部)地区,它是在 2015 年 8 月 4 日之前创建的。我不知道这可能是问题...

编辑:2016 年 10 月 20 日

根据documentaion -最终一致的读取操作可能不会返回任何结果,即使之前已经完成了两个或更多的写入操作。

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

一致的例子

4

2 回答 2

4

有时当文件很大时,它们会使用分段上传来上传,并在文件完全上传之前向 lambda 发送一个触发器。推测与触发 Lambda 函数的事件有关。在 lambda 函数的 event 字段中,确保将 put 和 complete multi-part upload 添加到事件中。

于 2016-09-16T23:36:20.293 回答
3

为防止出现此问题,可以使用 S3 SDK 服务程序。收到通知后,我们可以确保对象确实存在。例如,对于 AWS JavaScript 开发工具包,您可以使用以下代码段:

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

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

文档链接:AWS JavaScript SDK S3 类

于 2017-01-04T23:14:42.247 回答