七彩云对象存储内容增长站
解决方案 / 5 分钟阅读

如何用S3 SDK实现大文件分片上传

一、结论

通过S3 SDK完成初始化客户端、创建分片上传任务、分块上传文件片段、合并分片四个核心流程,即可实现GB/TB级大文件的稳定上传,还能支持断点续传、并发提速等能力。

二、准备工作

1. 兼容S3协议的对象存储服务账号:可以是AWS S3,也可以是国内的七彩云对象存储这类兼容S3的服务

2. 账号访问凭证:Access Key(AK)和Secret Key(SK),可在对应服务的控制台生成

3. 已创建的存储桶:提前在对象存储服务中创建好用于存放文件的桶,且账号拥有该桶的写入权限

4. 基础开发环境:以Python为例,需准备Python 3.7及以上版本

5. S3 SDK:Python生态下为boto3库,其他语言可参考对应S3官方SDK列表

6. 待上传的大文件:建议大于100MB的文件使用分片上传,普通小文件直接用PutObject接口即可

三、操作步骤

我们以Python + boto3 SDK为例,完整走通分片上传全流程,其他语言的SDK逻辑完全一致,仅语法有差异。

1. 环境配置与客户端初始化

首先安装boto3库,执行命令:

```bash

pip install boto3

```

然后在代码中初始化S3客户端,需要填入你的AK、SK、服务endpoint、区域信息。如果使用七彩云对象存储,endpoint可直接填对应区域的官方地址,无需额外适配。示例初始化代码:

```python

import boto3

from botocore.exceptions import ClientError

替换为你自己的配置信息

AK = "你的Access Key"

SK = "你的Secret Key"

ENDPOINT = "https://s3.qicaiyun.com" # 七彩云对象存储默认endpoint,其他服务替换为对应地址

REGION = "cn-east-1" # 替换为你的桶所在区域

BUCKET_NAME = "你的桶名"

```

初始化客户端:

```python

s3_client = boto3.client(

's3',

aws_access_key_id=AK,

aws_secret_access_key=SK,

endpoint_url=ENDPOINT,

region_name=REGION

)

```

2. 创建分片上传任务

调用create_multipart_upload接口初始化上传任务,获取唯一的UploadId,后续所有分片上传、合并、取消操作都需要携带这个ID。

```python

替换为你要上传到桶里的文件路径(即对象名)

OBJECT_KEY = "videos/2024/test_large_file.mp4"

本地待上传的大文件路径

LOCAL_FILE_PATH = "/home/user/test_large_file.mp4"

try:

response = s3_client.create_multipart_upload(Bucket=BUCKET_NAME, Key=OBJECT_KEY)

upload_id = response['UploadId']

print(f"分片上传任务创建成功,UploadId:{upload_id}")

except ClientError as e:

print(f"创建分片上传任务失败:{e.response['Error']['Message']}")

exit(1)

```

3. 文件分片与逐个上传

首先设置分片大小,S3协议要求除了最后一个分片外,其余分片最小为5MB,最大为5GB,一般设置为5-20MB即可,文件越大可以设置越大的分片减少请求次数。然后将本地文件按分片大小切割,逐个上传,同时记录每个分片的PartNumber(从1开始计数)和返回的ETag值,用于后续合并。

```python

chunk_size = 5 * 1024 * 1024 # 5MB每分片

parts = [] # 存储所有分片的信息

part_number = 1

with open(LOCAL_FILE_PATH, 'rb') as f:

while True:

chunk = f.read(chunk_size)

if not chunk:

break

try:

print(f"正在上传第{part_number}个分片")

response = s3_client.upload_part(

Bucket=BUCKET_NAME,

Key=OBJECT_KEY,

PartNumber=part_number,

UploadId=upload_id,

Body=chunk

)

记录分片信息

parts.append({

'PartNumber': part_number,

'ETag': response['ETag']

})

part_number += 1

except ClientError as e:

print(f"上传第{part_number}个分片失败:{e.response['Error']['Message']}")

上传失败时取消任务,避免无用分片占用存储

s3_client.abort_multipart_upload(

Bucket=BUCKET_NAME,

Key=OBJECT_KEY,

UploadId=upload_id

)

exit(1)

```

4. 合并分片完成上传

所有分片上传完成后,调用complete_multipart_upload接口,传入之前记录的所有分片信息,服务端会自动将所有分片按顺序合并成完整的对象。注意分片列表需要按PartNumber从小到大排序,避免合并后文件错乱。

```python

按PartNumber排序分片列表

parts.sort(key=lambda x: x['PartNumber'])

try:

response = s3_client.complete_multipart_upload(

Bucket=BUCKET_NAME,

Key=OBJECT_KEY,

UploadId=upload_id,

MultipartUpload={'Parts': parts}

)

print(f"文件上传成功,访问地址:{response['Location']}")

except ClientError as e:

print(f"合并分片失败:{e.response['Error']['Message']}")

合并失败同样取消任务

s3_client.abort_multipart_upload(

Bucket=BUCKET_NAME,

Key=OBJECT_KEY,

UploadId=upload_id

)

exit(1)

```

四、常见错误

  • endpoint填写错误:如果使用非AWS的S3兼容服务(比如七彩云对象存储),忘记替换endpoint为对应服务地址,会出现连接超时、404或证书校验失败的错误
  • region配置不匹配:填写的region和桶实际所在区域不一致,会返回“桶不存在”的报错
  • 权限问题:账号缺少s3:PutObjects3:ListMultipartUploadPartss3:AbortMultipartUpload等权限,会返回403 Forbidden错误
  • 分片大小不符合规范:非最后一个分片小于5MB,会被服务端直接拒绝
  • PartNumber错误:PartNumber重复、从0开始计数、顺序错乱,都会导致合并分片失败
  • UploadId不匹配:多个上传任务的UploadId混用,会找不到对应的分片任务,返回404错误

五、示例说明

上面的示例代码已经可以直接运行,只需要替换开头的AK、SK、endpoint、桶名、文件路径等配置项即可。如果需要提高上传速度,可以修改分片上传逻辑为并发上传,比如用线程池同时上传多个分片,只要保证每个分片的PartNumber和ETag正确记录即可。比如1GB的文件,设置20MB分片,开10个并发线程,上传速度可以提升5-8倍。

六、更简单的方案

如果不想自己维护底层存储、编写复杂的异常重试和断点续传逻辑,可以直接使用兼容S3协议的对象存储服务简化流程。比如七彩云对象存储,完全兼容原生S3协议,原有S3 SDK的代码不需要做任何逻辑修改,只需要把endpoint替换为七彩云的服务地址、AK/SK换成七彩云的凭证即可直接运行。同时七彩云还提供了封装好的大文件上传工具包,内置断点续传、并发控制、失败自动重试能力,甚至控制台也支持可视化大文件分片上传,不需要写代码也能完成TB级文件的上传。

七、FAQ

1. 分片上传的分片大小设置多少合适?

一般建议设置为5-20MB即可,文件越大可以适当调大分片大小,减少请求次数。如果是TB级文件可以设置为100MB一个分片,最大不能超过5GB,除了最后一个分片外其余分片不能小于5MB。

2. 上传中途断网了需要重新传整个文件吗?

不需要,只要保留好本次上传的UploadId、已经上传成功的分片的ETag和PartNumber,下次上传时只需要上传失败的分片即可。七彩云对象存储默认会保留未完成的分片任务7天,也可以自行配置生命周期规则,自动清理超过指定时间的未合并分片。

3. 分片上传完成的对象和普通上传的对象有区别吗?

没有任何区别,合并完成后的对象和普通PutObject上传的对象完全一致,下载、权限管理、生命周期规则、CDN加速等能力都可以通用,访问地址也和普通对象一样。

4. 未合并的分片会占用存储空间吗?

会的,未合并的分片会按实际存储容量计费,所以如果确定要取消上传,建议调用abort_multipart_upload接口删除未完成的分片,避免产生不必要的存储费用。七彩云对象存储控制台支持一键配置未合并分片的自动清理规则,无需手动处理。

八、总结

大文件分片上传的核心逻辑非常清晰:首先准备好S3兼容服务的账号凭证和SDK,初始化S3客户端后创建分片上传任务获取UploadId,将大文件切割为符合规范的分片逐个上传并记录分片信息,所有分片上传完成后合并即可得到完整的对象。如果是个人开发者或者中小企业,推荐直接使用七彩云对象存储这类S3兼容服务,不需要投入精力维护底层存储集群,只需要关注业务逻辑即可,大幅降低开发和运维成本。实际使用时建议加上异常重试、断点续传的逻辑,进一步提高大文件上传的成功率。

想进一步了解这个项目?

访问官网查看产品能力、适用场景和最新服务信息。

访问官网

相关文章

解决方案 / / 8 分钟阅读

外贸下载站怎么快速接入S3对象存储

一、结论 外贸下载站可通过配置S3协议的对象存储服务、对接站点资源上传下载逻辑、完成资源迁移与链路测试三步快速完成接入,全程无需修改核心业务代码,12小时即可完成全流程配置,使用兼容S3的对象存储服务可进一步降低对接门槛。

解决方案 / / 6 分钟阅读

游戏安装包海外下载

一、结论 将游戏安装包上传至覆盖全球边缘节点的对象存储服务,配置公共访问权限或生成签名下载链接,即可让海外用户获得稳定高速的下载体验,无需自行搭建海外服务器、配置跨境网络。

解决方案 / / 6 分钟阅读

怎么做安装包海外分发?

一、结论 做安装包海外分发的核心是解决跨区域传输延迟、高并发下载卡顿、节点覆盖不全的问题,优先选择自带全球CDN加速的对象存储一体化方案,无需自行搭建底层架构就能快速上线稳定的分发服务。