minio的putobject接口根据文件大小自动选择上传方式:≤5mb走单次put,>5mb自动分片上传;partsize默认5mb,可显式设置,但手动调用uploadpart时若分片小于5mb会报错。

PutObject 接口默认就走分片,但你得知道它什么时候“自动切”
MinIO 的 PutObject 接口在 Go SDK(minio-go/v7)中并不是“单次上传”或“分片上传”的开关按钮,而是一个智能代理:它会根据文件大小和参数自动决定是否启用 Multipart Upload。关键阈值是 MIN_MULTIPART_SIZE = 5242880(即 5MB)。
这意味着:
- 如果你传一个 4.9MB 的文件,
PutObject会走单次PUT请求,不生成uploadId,也不分片 - 如果你传一个 5.1MB 的文件,
PutObject会自动初始化 Multipart Upload,按默认partSize=5MB切成两片(第一片 5MB,第二片 0.1MB) - 这个行为由 SDK 内部的
putObjectMultipart分支逻辑控制,开发者无需手动调用initiateMultipartUpload
⚠️ 容易踩的坑:PutObject 的 partSize 参数只能在 PutObjectArgs 中显式设置;不传时 SDK 使用默认 5MB,且**不会因文件略超 5MB 就强行切成两片还让第二片小于 5MB**——它仍会切,但第二片小于是合法的(只要不是中间片)。真正报错 "chunk size must be greater than 5242880" 是发生在你手动调用 uploadPart 且传入了
手动 Multipart Upload 才能真正控制分片逻辑
当你需要断点续传、前端直传、预签名分片 URL 或自定义分片大小(比如设为 10MB 以减少请求数),就必须绕过 PutObject,改用底层 Multipart 三步法:initiateMultipartUpload → uploadPart → completeMultipartUpload。
这时你要注意:
-
initiateMultipartUpload返回的uploadId必须全程透传,不能丢,它是所有分片的唯一上下文 -
uploadPart的partNumber必须从 1 开始连续,不能跳号或重复;SDK 不校验连续性,但 MinIO 合并时会严格按序拼接 -
uploadPart的stream参数必须指定准确的size(即该分片字节数),且除最后一片外,其余所有分片都必须 ≥ 5MB,否则completeMultipartUpload会失败并抛出"chunk size must be greater than 5242880" - 不要用
io.LimitReader或截断流来伪造分片大小——MinIO 校验的是实际传输的字节数与stream声明的size是否一致
Presign URL 分片上传:前端可控 + 服务端无状态的关键
生产环境做大文件上传,通常不让前端直连 MinIO(暴露密钥风险高),而是让后端签发每个分片的 PresignURL。Go SDK 提供 presignedPostPolicy 和 presignedPutObject,但分片场景要用后者 + 手动构造 uploadId 上下文。
实操要点:
- 先调用
initiateMultipartUpload获取uploadId,存到 Redis 或 DB(带过期时间),返回给前端 - 前端按分片序号请求后端,后端调用
presignedPutObject,路径需包含?uploadId=xxx&partNumber=1—— 注意:MinIO 的 Presign URL **必须携带完整查询参数**,否则上传会 403 -
presignedPutObject的expires时间建议设为 15~60 分钟,太短导致续传失败,太长增加安全风险 - 合并前,服务端要先查一遍已上传分片(
listObjectParts),生成合法的Part列表传给completeMultipartUpload,不能靠前端传来的序号列表——前端可能漏报或错报
partSize 设多少才合理?别只盯着“越大越好”
把 partSize 从默认 5MB 改成 10MB 或 50MB,看似能减少请求数,但实际会引入新问题:
- 内存压力:SDK 默认使用
io.Copy流式上传,但如果启用了SetCustomTransport或用了某些代理,大分片可能被缓存进内存,OOM 风险上升 - 失败重试成本:一个 50MB 分片上传失败,重传耗时远高于 5MB 片,尤其在网络抖动频繁的移动端
- CDN/网关限制:某些企业防火墙或 CDN(如 Cloudflare)对单请求体有限制(如 100MB),设太大可能直接被拦截
- MinIO 自身限制:虽然支持最大 5GB 分片,但官方文档建议 ≤ 100MB;超过后,
listObjectParts返回的ETag可能因哈希算法变化导致校验异常
经验法则:Web 端推荐 5–20MB,移动端推荐 2–5MB;如果用户网络质量稳定(如内网上传),可上探至 50MB,但务必搭配 listObjectParts 校验机制,避免合并阶段才发现某片缺失或损坏。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











