为什么我在 S3 分段上传中收到“部分编号必须是 1 到 10000 之间的整数”错误?

问题描述 投票:0回答:1

我正在通过 boto3 使用分段上传将大型数据库转储 (~85 GB) 上传到 Amazon S3 存储桶。但是,我一直遇到这个错误:

botocore.exceptions.ClientError: An error occurred (InvalidArgument) when calling the UploadPart operation: Part number must be an integer between 1 and 10000, inclusive.

这是我的代码的相关部分:

from boto3.s3.transfer import TransferConfig

def upload_encrypted_dbdump(self, ciphertext_stream):
    s3 = self.s3_session_client()
    prev_total_size = 77309411328  # Previous file size, around 77 GB

    # Amazon S3's maximum number of parts for multipart upload
    max_parts = 10000

    # Calculate the new size with a 10% increase
    adjusted_size = int(prev_total_size * 1.1)

    # Calculate the part size with rounding up
    part_size = (adjusted_size + max_parts - 1) // max_parts
    print(f"Calculated part size: {part_size} bytes")

    s3_response = s3.upload_fileobj(
        Fileobj=ciphertext_stream,
        Bucket=self.s3_bucket,
        Key=f'{self.s3_folder}/{self.s3_dbdump_name}',
        ExtraArgs={'ACL': 'bucket-owner-full-control'},
        Config=TransferConfig(multipart_chunksize=part_size)
    )

我尝试过的步骤: 我根据之前备份的大小动态计算了部分大小,将其增加了 10%。

示例:如果先前的大小为 77 GB,我计算新的大小为 adjustment_size = int(77309411328 * 1.1) → 85040352460 字节。 然后,我将此尺寸除以 max_parts = 10000 来计算零件尺寸。

part_size = (调整后的_size + max_parts - 1) // max_parts 对于本示例,计算结果为:part_size = 85040352460 / 10000 ≈ 8504036 字节。 当我运行代码时,遇到“零件号必须是 1 到 10000 之间的整数(含)”错误。

我观察到的:

当我手动将 max_parts 设置为 1000 时效果很好,但是当我将其更改为 10,000 甚至 9,000 时,我得到了同样的错误。

我还尝试了 math.ceil(adjusted_size / max_parts) 来计算零件尺寸,但问题仍然存在。

问题:

当计算出的 part_size 似乎有效时,为什么我会收到“零件编号必须是 1 到 10000 之间的整数”错误?

如有任何帮助,我们将不胜感激!谢谢。

python amazon-s3 boto3
1个回答
0
投票

我认为零件编号错误可能是因为

ciphertext_stream
字节大小大于计算的
adjusted_size
,因此除以
part_size
时零件总数超过 10000。您应该使用
ciphertext_stream
的实际字节大小来计算每个部分的大小。如果
ciphertext_stream
io.BytesIO
类型,则可以使用 getbuffer().nbytes

from boto3.s3.transfer import TransferConfig

def upload_encrypted_dbdump(self, ciphertext_stream):
    s3 = self.s3_session_client()

    # Amazon S3's maximum number of parts for multipart upload
    max_parts = 10000

    # Calculate the new size with a 10% increase
    stream_size = ciphertext_stream.getbuffer().nbytes

    # Calculate the part size with rounding up
    part_size = (stream_size + max_parts - 1) // max_parts
    print(f"Calculated part size: {part_size} bytes")

    s3_response = s3.upload_fileobj(
        Fileobj=ciphertext_stream,
        Bucket=self.s3_bucket,
        Key=f'{self.s3_folder}/{self.s3_dbdump_name}',
        ExtraArgs={'ACL': 'bucket-owner-full-control'},
        Config=TransferConfig(multipart_chunksize=part_size)
    )
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.