【问题标题】:Is there a way to parallelize boto3's list_objects_v2 method?有没有办法并行化 boto3 的 list_objects_v2 方法?
【发布时间】:2022-01-06 16:24:18
【问题描述】:

我目前在我们的 s3 存储桶中有一个位置,需要在最繁忙的时间每小时归档多达 600 万个文件。当前的逻辑如下所示:

def get_responses(bucket, prefix):
    """
        This method will get the file information for a given directory on s3.
        Args:
            bucket (str): name of s3 bucket
            prefix (str): directory within s3 bucket
        Returns:
            list of json responses from S3
    """
    client = boto3.client(
        "s3", aws_access_key_id=S3_ACCESS_KEY,
        aws_secret_access_key=S3_SECRET_KEY)
    continuation_token = None
    responses = []
    # List objects within the given directory until the response is truncated
    while True:
        list_kwargs = dict(
            Bucket=bucket, Prefix=prefix, MaxKeys=1000)
        # Add continuation token if not None
        if continuation_token:
            list_kwargs['ContinuationToken'] = continuation_token
        response = client.list_objects_v2(**list_kwargs)
        # Add valid reponses and update continuation token
        if 'Contents' in response:
            responses += response['Contents']
        # Exit while loop if at the end of the objects
        if not response.get('IsTruncated'):
            break
        continuation_token = response.get('NextContinuationToken')

    return responses

如您所见,这一次迭代超过 1000 个文件,这是 list_objects_v2 的当前限制。在最坏的情况下,这大约需要半个小时,并且会减慢整个工作的速度,而这部分工作最好在一个小时内运行。有没有办法将其并行化,以便您可以一次在每个线程上列出 1000 个文件?

(所有文件都在一个前缀下,不能拆分)

【问题讨论】:

    标签: python amazon-s3 boto3


    【解决方案1】:

    如果有 N 个唯一前缀,那么也许您可以使用现有的 Python 多处理/多线程功能进行 N 个独立调用,最后汇总结果。

    如果所有对象都具有相同的前缀,我不确定您是否可以并行列出子集,因为您不会提前知道 NextContinuationToken。但你也许可以编造一些独特的前缀......

    如果所有对象都具有相同的前缀,例如dogs/,则可以列出子前缀,例如dogs/adogs/bdogs/c。等对终止文件名的所有可能的第一个字母执行此操作。前缀不必以正斜杠结尾,例如dogs/。如果您需要超过 26 个前缀(假设它们是小写的),那么您可以使用前 2 个字母扩展到 dogs/aadogs/ab 等。

    另外,如果您有 N 个唯一前缀,请查看 Netflix Metaflow 项目,该项目声称提供并行 S3 操作支持,包括路径列表:

    列出 S3 中的下一级路径。如果指定了多个键,列表将并行完成。

    【讨论】:

    • 不幸的是,它是一个前缀,而不是 N 个唯一的前缀。这就是挑战,是的,因为没有办法提前或几个获得 NextContinuationToken 并将它们分配给任务。仍然希望有人能提供答案,但我们会看到。
    • 在最后一个对象降落在该前缀下与需要列出该前缀下的对象之间有多长时间?如果超过 24 小时,您或许可以使用 S3 Inventory。或者,也许您可​​以在对象到达 S3 时累积一个对象列表,通过 Lambda 函数写入 DynamoDB 或等效项,以便对象列表立即可用,并可根据需要为后续批处理操作进行分区。
    • 您也可以简单地编造前缀,例如dogs/a、dogs/b、dogs/c。等对终止文件名的所有可能的第一个字母执行此操作。前缀不必以正斜杠结尾。如果您需要超过 26 个前缀(假设它们是小写的),那么您可以使用前 2 个字母扩展到dogs/aa、dogs/ab 等。
    • 这需要我们尽快列出,不能使用 s3 库存。你提到的第二个部分很有趣。现在,文件集和一些相关元数据已写入 Aurora 实例。我必须估算每小时访问 Lambda 数百万次 + DynamoDB 的成本,以及它是否可以处理这么多并发连接
    • 是的,S3 密钥中的 / 正斜杠没有什么特别之处。 S3 本质上具有扁平的键空间。它并不比 abK 更特别。
    猜你喜欢
    • 2019-06-28
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2021-04-24
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多