boto3上传小于multipart阈值文件至S3兼容存储遇413错误如何修复
修复boto3向Ceph(S3兼容存储)上传小文件时的413错误
问题背景
向Ceph(S3兼容存储)上传大小为3722588字节(约3.5MB)的文件,已设置multipart_threshold=9046456(约8.6MB,远大于文件大小),但执行代码时仍触发如下错误:
botocore.exceptions.ClientError: An error occurred (413) when calling the PutObject operation: Request Entity Too Large
原代码如下:
import boto3 import requests from boto3.s3.transfer import TransferConfig s3 = boto3.client('s3', endpoint_url='http://s3.example.com', aws_access_key_id='VXBJDJDLSDHHSDL', aws_secret_access_key='SDGHHSDHSDKsdhgsdgj123423bsdsdjSDHdhf') content = requests.get('http://example.com').content s3.upload_fileobj(Fileobj=io.BytesIO(content), Bucket=bucket, Key=f'{master_folder}/{folder}/{g.split("/")[-1]}', ExtraArgs={'ACL': 'public-read'}, Config=TransferConfig(multipart_threshold=9046456)
问题原因
413错误是服务端返回的请求实体过大,和boto3的分片逻辑无关——因为文件大小确实低于阈值,boto3会正常使用PutObject单请求上传,错误根源是:
- 前端代理(如Nginx)的
client_max_body_size限制(默认可能为1MB/4MB,刚好接近你的文件大小) - Ceph RGW自身的
rgw_max_put_obj_size参数限制了单请求上传的文件大小
修复方案
1. 调整服务端/代理的请求大小限制
- 如果使用Nginx反向代理Ceph,修改对应站点配置或
nginx.conf中的client_max_body_size参数,例如设置为10M,然后重启Nginx:client_max_body_size 10M; - 如果是Ceph RGW本身的限制,修改RGW配置文件中的
rgw_max_put_obj_size参数,设置为大于目标文件大小的值,重启RGW服务生效。
2. 强制boto3使用分片上传
即使文件小于阈值,也可以强制分片上传,绕过单请求大小限制。修改TransferConfig参数:
Config=TransferConfig( multipart_threshold=1, # 强制所有文件触发分片上传 multipart_chunksize=1048576 # 每个分片1MB,可根据服务端限制调整 )
3. 修正代码中的语法问题
原代码存在两处语法错误,需修复后才能正常运行:
- 缺少
import io,io.BytesIO会触发未定义错误 upload_fileobj调用末尾缺少闭合括号
修正后的完整代码:
import boto3 import requests import io from boto3.s3.transfer import TransferConfig s3 = boto3.client('s3', endpoint_url='http://s3.example.com', aws_access_key_id='VXBJDJDLSDHHSDL', aws_secret_access_key='SDGHHSDHSDKsdhgsdgj123423bsdsdjSDHdhf') content = requests.get('http://example.com').content bucket = "your-bucket-name" master_folder = "your-master-folder" folder = "your-folder" g = "your-file-path" s3.upload_fileobj( Fileobj=io.BytesIO(content), Bucket=bucket, Key=f'{master_folder}/{folder}/{g.split("/")[-1]}', ExtraArgs={'ACL': 'public-read'}, Config=TransferConfig(multipart_threshold=1, multipart_chunksize=1048576) )
内容的提问来源于stack exchange,提问作者Egor
相关产品推荐
相关产品推荐

