这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
分片上传
当文件从几 MB 变成几百 MB,单次上传的失败成本会非常高。用户等了十分钟,最后因为一次网络抖动全部重来,这是文件系统最直观的体验问题。
分片上传的思路是把一个大文件拆成多个小块,每个分片独立上传,失败时只重传失败的部分。
初始化上传任务 -> 上传 chunk 1..N -> 查询已上传分片 -> 合并文件 -> 校验完成
上传流程
分片上传一般分成四步:
- 初始化任务:客户端提交文件名、大小、hash、分片大小,服务端返回
upload_id。 - 上传分片:客户端按序或并发上传分片,服务端记录分片编号、大小、hash 和存储位置。
- 查询进度:客户端断线重连后查询哪些分片已经上传。
- 完成合并:所有分片到齐后,服务端合并文件并校验整体 hash。
关键数据表可以拆成两张:
| 表 | 作用 |
|---|---|
| upload_task | 记录上传任务、文件总大小、分片大小、状态和过期时间 |
| upload_part | 记录每个分片编号、大小、hash、上传状态和存储位置 |
这样设计后,上传状态变成可查询、可恢复、可清理的数据,而不是散落在临时目录里的文件。
并发与顺序
分片不一定要按顺序上传。客户端可以同时上传 3 到 6 个分片,提高带宽利用率。但并发数不能无限增大,否则会带来三个问题:
- 客户端占满用户网络,影响页面其他请求。
- 服务端打开大量连接,吞吐下降。
- 对象存储或网关触发限流。
工程上通常让客户端根据网络情况动态调整并发数,服务端则通过用户、文件和 IP 维度做限流。
合并策略
如果文件最终存储在本地磁盘,服务端可以按分片编号顺序合并。但如果后续要接对象存储,最好提前适配对象存储的 multipart 能力,让分片直接进入对象存储,由对象存储完成合并。
合并前必须检查:
- 分片数量是否完整。
- 每个分片大小是否符合预期。
- 分片 hash 是否正确。
- 最终文件 hash 是否和初始化任务一致。
分片上传解决的是大文件传输可靠性,但它也引入了临时数据清理问题。所有未完成任务都要有过期时间,后台定期清理临时分片,避免存储成本悄悄失控。
