Warm tip: This article is reproduced from serverfault.com, please click

amazon s3-S3最终一致性,可在写入后读取

(amazon s3 - S3 eventual consistency for read after write)

发布于 2020-07-02 15:14:42

我阅读了许多有关s3最终一致性以及如何处理它以免出现404错误的不同场景和问题的文章。但是这里我有一些奇怪的用例/需求!我正在做的是将一堆文件写入s3存储桶中的temp / transient文件夹(使用spark作业,并确保作业不会失败),然后如果上一步成功,则删除main / destination文件夹,最后将文件从temp复制到同一存储桶中的主文件夹。这是我的代码的一部分:

# first writing objects into the tempPrefix here using pyspark
...
# delete the main folder (old data) here
...

# copy files from the temp to the main folder
for obj in bucket.objects.filter(Prefix=tempPrefix):

    # this function make sure the specific key is available for read 
    # by calling HeadObject with retries - throwing exception otherwise
    waitForObjectToBeAvaiableForRead(bucketName, obj.key)

    copy_source = {
        "Bucket": bucketName,
        "Key": obj.key
    }
    new_key = obj.key.replace(tempPrefix, mainPrefix, 1)
    new_obj = bucket.Object(new_key)
    new_obj.copy(copy_source)

这似乎可以避免写入后立即读取任何404(NoSuchKey)错误。我的问题是,是否bucket.objects.filter总是会给我新编写的对象/密钥?最终的一致性也会影响到这一点吗?我之所以这样问,是因为HeadObject调用(在waitForObjectToBeAvaiableForRead函数中)有时会为bucket.objects.filter!!!返回的键返回404错误我的意思是bucket.objects返回的键不可读!!!

Questioner
Nisman
Viewed
0
user212514 2020-07-13 23:07:58

当你在S3中删除对象时,AWS会为该对象写入一个“删除标记”(假定存储桶已版本化)。该对象似乎已删除,但这是AWS造成的一种错觉。

因此,如果要在先前存在但现在已删除的对象上写入对象,则实际上是在更新对象,这会导致“最终一致性”而不是“强一致性”。

AWS文档中的一些有用的评论

删除标记是在简单的DELETE请求中命名的版本化对象的占位符(标记)。由于该对象位于启用版本控制的存储桶中,因此未删除该对象。但是,删除标记使Amazon S3表现得就像已被删除一样。

如果你尝试获取对象并且其当前版本是删除标记,则Amazon S3会响应:

404(找不到对象)错误

响应标头,x-amz-delete-marker:true

具体答案

我的问题是,bucket.objects.filter会始终为我提供新编写的对象/键吗?

是的,如果存储桶中的对象少于1,000个,则将包括新编写的对象/键。该API最多返回1,000个对象。

最终的一致性也会影响到这一点吗?

最终的一致性会影响对象最新版本的可用性,而不影响过滤结果中对象的存在。404错误是尝试读取最近删除的新写入对象的结果(并且尚未实现完全一致性)。