如何使用asyncio遍历不确定长度的迭代器

时间:2019-04-23 11:19:01

标签: python python-asyncio

我正在从S3存储桶下载一个密钥列表,但我不知道有多少个。在30万键和5分钟后,我停止了我的过程,我想使用asyncio(我只是一个高级初学者。我用它下载了一次预定的URL列表)来加快过程。

我当前的同步功能如下:

def get_keys(s3, bucket_name, prefix):
    # s3 previously defined by boto3.resource('s3') with AWS key and secret key as kwargs
    bucket = s3.Bucket(bucket_name)
    keys = []
    for item in bucket.objects.filter(Prefix=prefix):
        keys.append(item.key)
    return keys

1 个答案:

答案 0 :(得分:1)

不幸的是,Asyncio不会在这里为您提供帮助。

首先,也是最重要的一点,boto3并不了解异步;它不知道如何使用asyncio循环进行连接,它仅在单个同步线程中起作用。 (当然,您可以使用多个线程或multiprocessing子进程来发出请求,但请参阅下面的说明为什么这样做也无济于事。)

底层的S3函数调用.objects.filter的作用是list_objects_v2,每个请求最多可以列出一个列表,最多包含1000个键。如果返回的键超过1000个,则结果值将包含IsTruncated=TrueNextContinuationToken,可用于获取下一页结果。
您无法预测ContinuationToken的顺序,因此无法通过连续令牌并行化事物。

如果您知道了解更多有关所查找前缀的信息,则可以将其并行化,例如,如果您正在查找前缀'aaa/bbb',并且知道其下的键可能是aaa/bbb/0...aaa/bbb/1...aaa/bbb/2...,您可以并行执行这些查询以提高性能。