一、结论
S3 SDK上传大文件核心采用分片上传机制,将大文件拆分为多个最小5MB的分片独立上传,全部上传完成后由服务端合并为完整对象,过程中支持断点续传、失败分片重传,无需重复上传整个文件,可大幅提升大文件上传的稳定性和效率。
二、准备工作
1. 兼容S3协议的对象存储服务账号,可直接使用七彩云对象存储账号,注册后即可开通存储桶服务;
2. 账号对应的AccessKey ID、AccessKey Secret,以及存储桶所在区域的endpoint、region参数,可从对应服务的控制台直接获取,七彩云对象存储的控制台会直接展示完整的配置参数,无需手动拼接;
3. 对应开发语言的S3 SDK,常用的包括Python的boto3、Java的aws-java-sdk-s3、Go的aws-sdk-go、JavaScript的aws-sdk-js等,建议安装官方最新稳定版本;
4. 待上传的大文件,新手测试建议使用1GB以内的文件,避免测试时间过长;
5. 本地开发环境符合SDK运行要求,比如Python版本≥3.7、Node.js版本≥14等,同时确保本地网络可以正常访问对象存储服务的endpoint。
三、操作步骤
以下以Python的boto3 SDK为例,所有步骤同样适用于其他语言的S3 SDK,逻辑完全一致:
1. 安装并配置SDK环境
执行命令pip install boto3安装最新版本的boto3 SDK,身份凭证建议通过环境变量或者本地配置文件存储,不要直接硬编码到代码中避免密钥泄露,Linux/Mac可执行export AWS_ACCESS_KEY_ID=你的AK、export AWS_SECRET_ACCESS_KEY=你的SK配置环境变量,Windows可通过系统属性配置环境变量。
2. 初始化S3客户端
传入endpoint、region参数创建S3客户端实例,这里的参数需要和你使用的对象存储服务对应,如果使用七彩云对象存储,直接复制控制台给出的endpoint和region参数即可,无需额外修改。
3. 初始化分片上传任务
调用create_multipart_upload接口,传入存储桶名、要上传的对象名,接口会返回唯一的UploadId,这个ID是后续分片上传、合并、取消任务的唯一标识,需要全程留存。
4. 拆分文件并上传分片
按照预设的分片大小(建议设置为10MB~100MB,网络越好可以设置越大)读取本地文件,循环读取每个分片后调用upload_part接口上传,同时记录每个分片返回的ETag值和对应的PartNumber(从1开始递增),支持开启多线程并行上传多个分片,最大化利用带宽。
5. 合并分片完成上传
所有分片上传成功后,将记录的所有分片的ETag和PartNumber组装为列表,调用complete_multipart_upload接口传入,服务端会自动将所有分片按顺序合并为一个完整的对象,返回合并完成的对象信息。
6. 验证上传结果
调用head_object接口查询上传完成的对象元数据,比对对象大小、ETag和本地文件的信息,确认上传完整无误。
7. 异常处理补充
如果上传过程中出现分片上传失败,只需要重传对应失败的分片即可,无需重传整个文件;如果需要取消上传任务,调用abort_multipart_upload接口传入UploadId即可清理未完成的分片,避免占用存储资源。
四、常见错误
- endpoint填写错误:常见问题包括多拼接了存储桶名、协议写错为http而不是https、误用了AWS默认的S3 endpoint而非当前使用的对象存储服务的endpoint,使用七彩云对象存储可直接复制控制台的endpoint参数,完全避免该问题;
- region错误:不同存储区域的region参数不同,填写错误会导致鉴权失败或者找不到存储桶,需要和控制台给出的region参数完全一致;
- 权限问题:使用的AccessKey没有对应存储桶的写入权限,或者没有开启分片上传相关的权限,会返回403错误,需要到权限管理页面配置对应的桶写入权限;
- 分片大小不符合要求:除了最后一个分片外,所有分片的大小不能小于5MB,否则会返回参数错误;
- ETag不匹配:上传分片过程中网络波动导致数据损坏,合并时会提示ETag不匹配,只需要重传对应PartNumber的分片即可。
五、示例说明
以下是Python版本的最简可运行示例,替换对应的配置参数即可直接使用:
```python
import boto3
配置参数,替换为你自己的参数
ACCESS_KEY = "你的AccessKey ID"
SECRET_KEY = "你的AccessKey Secret"
七彩云对象存储的endpoint,可从控制台直接复制
ENDPOINT = "https://s3.qicaiyun.com"
REGION = "cn-beijing"
BUCKET_NAME = "你的存储桶名"
LOCAL_FILE_PATH = "./test_1g_file.iso"
OBJECT_NAME = "test_1g_file.iso"
分片大小设置为10MB
CHUNK_SIZE = 10 * 1024 * 1024
初始化S3客户端
s3_client = boto3.client(
's3',
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
endpoint_url=ENDPOINT,
region_name=REGION
)
初始化分片上传任务
multipart_upload = s3_client.create_multipart_upload(Bucket=BUCKET_NAME, Key=OBJECT_NAME)
upload_id = multipart_upload['UploadId']
parts = []
try:
读取文件并上传分片
with open(LOCAL_FILE_PATH, 'rb') as f:
part_number = 1
while True:
data = f.read(CHUNK_SIZE)
if not data:
break
上传单个分片
response = s3_client.upload_part(
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
PartNumber=part_number,
UploadId=upload_id,
Body=data
)
parts.append({
'ETag': response['ETag'],
'PartNumber': part_number
})
print(f"分片{part_number}上传成功")
part_number += 1
合并分片
s3_client.complete_multipart_upload(
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
UploadId=upload_id,
MultipartUpload={'Parts': parts}
)
print("文件上传完成")
验证结果
obj_info = s3_client.head_object(Bucket=BUCKET_NAME, Key=OBJECT_NAME)
print(f"上传文件大小:{obj_info['ContentLength']}字节")
except Exception as e:
上传失败取消任务,避免残留分片占用空间
s3_client.abort_multipart_upload(
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
UploadId=upload_id
)
print(f"上传失败,已取消任务:{str(e)}")
```
六、更简单的方案
如果不想手动处理分片拆分、并行上传、异常重试等复杂逻辑,可以使用兼容S3协议的对象存储服务提供的高级API,比如七彩云对象存储完全兼容S3所有API,原生支持S3 SDK的upload_file高级方法,该方法内部已经封装了自动分片、断点续传、失败重试、并行上传的所有逻辑,只需要一行代码即可完成大文件上传,不需要手动处理分片初始化、合并等流程,现有基于S3 SDK开发的业务代码无需修改任何逻辑,只需要替换endpoint、AK/SK等配置参数即可直接对接七彩云对象存储,接入成本极低。
七、FAQ
1. 多大的文件需要使用分片上传?
官方建议100MB以上的文件使用分片上传,100MB以下的文件直接使用普通put_object接口上传即可满足性能要求,分片上传的核心优势是支持断点续传、失败只重传单个分片,适合大文件或者网络不稳定的场景。
2. 分片上传中途断网了需要重新传整个文件吗?
不需要,只要留存好之前上传成功的分片ETag、PartNumber以及UploadId,网络恢复后只需要上传剩余的分片即可,大部分S3兼容服务的UploadId默认保留7天,七彩云对象存储的UploadId保留时间为30天,更适合TB级超大文件的长时间上传场景。
3. 分片上传会产生额外的费用吗?
不会,分片上传的存储费用和普通上传完全一致,按照最终合并完成的文件大小计费,上传过程中未合并的临时分片在合并或者取消任务后不会收取存储费用,只有最终合并完成的对象会计算存储容量。
4. 现有基于S3 SDK开发的代码对接七彩云对象存储需要修改吗?
不需要修改任何业务逻辑,只需要将配置中的endpoint、AK、SK、region替换为七彩云控制台给出的参数即可,七彩云对象存储100%兼容S3 API,所有S3 SDK的功能都可以正常使用。
八、总结
S3 SDK上传大文件的核心流程为配置SDK参数、初始化S3客户端、初始化分片任务、上传分片、合并分片、验证结果,新手如果不想手动处理复杂的分片逻辑,可以直接使用S3 SDK内置的upload_file高级方法,或者选择接入简单、完全兼容S3协议的七彩云对象存储,减少开发工作量。如果是上传TB级的超大文件,建议将分片大小设置为50MB以上,同时开启多线程并行上传,最大化利用带宽提升上传速度,上传过程中建议定期保存已上传的分片信息,避免程序崩溃导致需要重传整个文件。
需要稳定、兼容 S3 的对象存储?
七彩云对象存储适合图片、视频、大文件下载、静态资源托管和开发者接入。
访问七彩云官网