“指定的密钥不存在”存储桶中真实存在的对象的S3错误

时间:2015-08-02 14:28:30

标签: java amazon-web-services amazon-s3 aws-sdk

在我们的应用程序中,我们必须通过AWS Java SDK上传的用户图像在后端下载一些处理操作(调整大小,裁剪等)。有时,我们会收到以下错误:

  

com.amazonaws.services.s3.model.AmazonS3Exception:指定的密钥不存在。 (服务:Amazon S3;状态代码:404;错误代码:NoSuchKey;

但是此键和此路径保存的对象存在。我知道在AWS开发人员指南中,这种行为是预期的:

  

但是,有关更改的信息可能无法立即在Amazon S3上复制,您可能会发现以下行为:进程将新对象写入Amazon S3并立即尝试读取它。在完全传播更改之前,Amazon S3可能会报告“密钥不存在。”

但是如何在我的代码中处理此错误?我试着等了几毫秒,我试着重试下载这个对象 - 我的所有尝试都失败了。

         try
            {
                Download download = s3TransferManager
                        .download(new GetObjectRequest(bucketName, key), new File(tempUrl));
                download.waitForCompletion();
            }
            catch (AmazonS3Exception amazonS3Exception)
            {
                Thread.sleep(1000);
                //retry 3 time.... }

我很高兴听到在这种情况下如何下载现有文件的任何建议。谢谢!

2 个答案:

答案 0 :(得分:2)

答案实际上取决于您所使用的地区。 来自S3 FAQ(这里是http://aws.amazon.com/s3/faqs/):

  

问:Amazon S3采用什么数据一致性模型?

     

所有区域中的Amazon S3存储桶都提供了写后读写一致性   用于新对象的PUTS以及覆盖PUTS的最终一致性   和DELETES。仅在美国标准区域提供Amazon S3存储桶   通过Northern访问时的读写后一致性   弗吉尼亚终点(s3-external-1.amazonaws.com)。

如果使用美国标准并且没有指定端点,那么在放置和物体可用时边缘情况可能会出现大的延迟(传闻我观察到以小时为单位测量的延迟)。接下来的模式是执行put和之后旋转并等待对象。

立即解决方法是使用弗吉尼亚终点(根据常见问题解答)是美国标准的情况,或远离美国标准并使用其他地区(例如US-West-2)。所有其他区域都具有read-after-write,因此一旦put完成,该对象将变为可用。

答案 1 :(得分:1)

如果您的图像处理是后台作业(异步作业),则可以使用S3 Event Notification。因此,只要您的图像刚刚放入存储桶,S3就可以触发SNS通知/ SQS或调用AWS Lambda函数。