问题描述
ListObjectsV2
只能返回 1000 个结果,此时您必须返回另一个页面。
由于 Amazon S3 现在具有强一致性,并且当我列出其内容时,存储桶可能会发生其他更新,第二页是否会与第一页在同一时间点获得更多结果?还是会在请求第二页时反映bucket的状态?
比如,如果我列出一个bucket,拿到第一页,删除一个本来会出现在第二页的key,然后拿到第二页,我还能看到现在被删除的key吗?
解决方法
确实,Amazon S3 现在是 strongly consistent。这意味着一旦您上传了一个对象,所有读取该对象的人都可以保证获得该对象的更新版本。这并不意味着保证两个不同的 API 调用处于相同的“状态”。值得注意的是,对于下载,存在一种情况,如果在下载时更新了对象,则一次下载可以获得对象的两个版本的一部分。 this answer 中提供了更多详细信息。
对于您的问题,适用相同的基本规则:S3 从一次调用到下一次调用都具有很强的一致性,一旦您对存储桶或对象进行更改,保证更新后的任何调用以获取更新的数据。这意味着当您翻阅对象列表时,您将看到每个 API 调用获得最新状态时的更改:
import boto3
BUCKET='example-bucket'
PREFIX='so_question'
s3 = boto3.client('s3')
# Create a bunch of items
for i in range(3000):
s3.put_object(Bucket=BUCKET,Key=f"{PREFIX}/obj_{i:04d}",Body=b'')
args = {'Bucket': BUCKET,'Prefix': PREFIX + "/",}
result = s3.list_objects_v2(**args)
# This shows objects 0 to 999
print([x['Key'] for x in result['Contents']])
# Delete an object
s3.delete_object(Bucket=BUCKET,Key=f"{PREFIX}/obj_{1100:04d}")
# Request the next "page" of items
args['ContinuationToken'] = result['NextContinuationToken']
result = s3.list_objects_v2(**args)
# This will not show object 1100,showing objects 1000 to 2000
print([x['Key'] for x in result['Contents']])
这样做的好处是,无法在一次 API 调用中获取存储桶中所有对象的列表(假设它有 1000 多个项目):我不知道如何获得完整的“快照”当然,除非您可以确保在列出对象的过程中存储桶不会发生变化。