背景
我们在项目中使用AmazonS3作为客户端上传文件的存储空间。
出于技术原因,我们将一个临时名称为的文件上传到S3,然后处理其内容,并在处理后重命名文件。
问题
"重命名"操作一次又一次地失败,出现404 (key not found)
错误,尽管正在重命名的文件已成功上载。
亚马逊文档提到这个问题:
Amazon S3通过在亚马逊数据中心的多个服务器上复制数据来实现高可用性。如果PUT请求成功,则数据将被安全存储。然而,有关更改的信息必须在AmazonS3中复制,这可能需要一段时间,因此您可能会观察到以下行为:
我们实现了一种轮询作为解决方法:重试"重命名"操作,直到成功
轮询在20秒后停止
这种解决方法在大多数情况下都有效:文件在几秒钟内被复制
但有时——很少——20秒是不够的;S3中的复制需要更多的时间
问题
-
您在AmazonS3上观察到的成功PUT操作和完全复制之间的最长时间是多少
-
Amazon S3是否提供了一种"绕过"复制的方法(直接查询"master"?)
更新:这个答案使用了一些旧的术语,我大部分都保留了这些术语。AWS已经更改了"US Standard"的友好名称,以与其他地区的命名更加一致,但其IPv4的区域端点仍然有一个不同寻常的名称s3-external-1.amazonaws.com
。
S3的us-east-1区域有一个IPv4/IPv6"双堆栈"端点,该端点遵循s3.dualstack.us-east-1.amazonaws.com
的标准约定,如果启用了IPv6,则该端点在操作上与s3-external-1
等效,如下所述。
关于该地区请求的地理路线的文献似乎基本上已经消失,没有太多评论,但传闻证据表明,以下信息仍然与该地区有关。
Q。难道没有美国标准地区吗
我们将美国标准地区更名为美国东部(北弗吉尼亚州)地区,以符合AWS地区命名惯例。
—https://aws.amazon.com/s3/faqs/#regions
使用S3传输加速功能的bucket使用全局样式的端点${bucketname}.s3-accelerate.amazonaws.com
,目前还不清楚该端点在us-east-1 bucket和最终一致性方面的表现,尽管如果启用了该功能,其他区域不应该受到该功能的影响。该功能通过将请求路由到相同的S3端点,但通过AWS"边缘网络"(CloudFront的同一系统)进行代理,提高了距离存储桶更远的用户的传输吞吐量。它本质上是一个通过CloudFront的自配置路径,但没有启用缓存。加速来自于优化的网络堆栈,并在互联网上的大部分路径上保持托管AWS网络上的流量。因此,如果您在bucket上启用并使用此功能,则此功能应该不会对一致性产生影响。。。但是,正如我提到的,它是如何与us-east-1 bucket交互的还不清楚。
美国标准(US-east-1)区域是S3中最古老、可能也是最大的区域,与其他较新的区域相比,它确实遵循了一些不同的规则。
一个重要且相关的差异是一致性模型。
[除美国标准外的所有地区]中的Amazon S3存储桶为新对象的PUTS提供读写一致性,并为覆盖PUTS和DELETES提供最终一致性。美国标准地区的AmazonS3存储桶提供了最终的一致性。
http://aws.amazon.com/s3/faqs/
这就是我认为您使用美国标准的原因。您描述的行为与该设计约束一致。
您应该能够验证在另一个区域的测试桶中不会发生这种情况。。。但是,因为在同一区域内从EC2到S3的数据传输是免费的并且延迟非常低,所以在不同区域中使用桶可能不实用。
还有另一种选择值得尝试,它与美国标准的内部运作有关。
事实上,US Standard在地理上分布在弗吉尼亚州和俄勒冈州之间,对"s3.amazonaws.com"的请求通过DNS选择性地路由到一个或另一个位置。这种路由在很大程度上是一个黑盒,但亚马逊已经暴露了一个变通方法。
您可以通过将端点从"s3.amazonaws.com"更改为"s3-eternal-1.amazonaws.com"来强制将您的请求仅路由到北弗吉尼亚州…
http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
。。。这是我的猜测,但您的请求的地理路由可能会加剧您的问题,并迫使他们选择"s3-external-1"(需要明确的是,这仍然是美国标准),这可能会改善或消除您的问题
更新:以上建议已正式超越猜测,但我将其留给历史参考。大约在我写上述文章的一年前,亚马逊确实宣布,美国标准在创建新对象时确实提供了读写一致性,但仅在使用s3-external-1
端点时。他们把它解释为一种新的行为,可能就是这样。。。但这也可能只是平台官方支持的行为的改变。任一方式:
从〔2015-06-19〕开始,美国标准地区现在支持使用北弗吉尼亚端点(S3-external-1.amazonaws.com)添加到Amazon S3的新对象的写后读取一致性。有了这一更改,所有Amazon S3地区现在都支持写后读取的一致性。写后读取一致性允许您在AmazonS3中创建对象后立即检索对象。在这一变化之前,美国标准地区的AmazonS3存储桶为新创建的对象提供了最终的一致性,这意味着一些小的对象集可能无法在新对象上传后立即读取。这些偶尔的延迟可能会使数据处理工作流复杂化,因为应用程序需要在创建对象后立即读取对象请注意,在美国标准地区,此一致性更改适用于北弗吉尼亚端点(s3-external-1.amazonaws.com)。使用全局端点(s3.amazonaws.com[增加强调]
https://forums.aws.amazon.com/ann.jspa?annID=3112
如果你上传了大量文件(每秒数百个),你可能也会淹没S3的分片机制。对于每秒上传的次数非常高的情况,重要的是密钥("文件名")在词汇上不按顺序排列。
根据亚马逊处理DNS的方式,如果你的代码可以处理,你可能还想尝试另一种寻址bucket的变体。
美国标准中的Buckets可以通过http://mybucket.s3.amazonaws.com/key。。。或http://s3.amazonaws.com/mybucket/key。。。至少在理论上,这两种方法的内部实现可能会有所不同,从而以与您的问题相关的方式改变行为。
正如您所指出的,目前无法直接从S3保证或解决最终的一致性。在Netflix的这篇演讲中,演讲者提到看到了7小时(极为罕见的IMHO)的一致性延迟。他们甚至在S3之上创建了一个一致性层s3mper,它是开源的,可能对您的上下文有所帮助。
除此之外,正如@Michael-sqlbot所建议的,我们的标准dos不提供写后读取的一致性,并且观察到的一致性延迟可能会有所不同。