我阅读了许多有关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
返回的键不可读!!!
当你在S3中删除对象时,AWS会为该对象写入一个“删除标记”(假定存储桶已版本化)。该对象似乎已删除,但这是AWS造成的一种错觉。
因此,如果要在先前存在但现在已删除的对象上写入对象,则实际上是在更新对象,这会导致“最终一致性”而不是“强一致性”。
AWS文档中的一些有用的评论:
删除标记是在简单的DELETE请求中命名的版本化对象的占位符(标记)。由于该对象位于启用版本控制的存储桶中,因此未删除该对象。但是,删除标记使Amazon S3表现得就像已被删除一样。
如果你尝试获取对象并且其当前版本是删除标记,则Amazon S3会响应:
404(找不到对象)错误
响应标头,x-amz-delete-marker:true
具体答案
我的问题是,bucket.objects.filter会始终为我提供新编写的对象/键吗?
是的,如果存储桶中的对象少于1,000个,则将包括新编写的对象/键。该API最多返回1,000个对象。
最终的一致性也会影响到这一点吗?
最终的一致性会影响对象最新版本的可用性,而不影响过滤结果中对象的存在。404错误是尝试读取最近删除的新写入对象的结果(并且尚未实现完全一致性)。