同一份文件被反复上传,在设计素材、安装包、视频母版这类大文件场景里很常见。几个成员各传一遍,存储账单悄悄往上涨,直到有人抱怨上传太慢,才发现问题出在重复上传上。阿里云秒传要解决的就是这件事:上传前先确认服务端有没有内容完全相同的文件,有就直接建立引用,不再重新传一遍字节。这篇文章从判断逻辑讲起,再说在阿里云 OSS 上通常怎么落地。

什么是秒传
秒传判断的依据是文件内容,文件名没有参考价值。两个文件名不同、内容一致,系统照样视为同一个文件。用户看到的是几乎瞬间完成,因为真正走网络的只有一个很小的校验请求。它和普通上传的区别在顺序上:普通上传是先传再存,秒传是先比对,命中就不传。
还要说清楚一点:OSS 本身没有叫“秒传”的开关,控制台和 API 里都找不到这个选项。阿里云秒传通常由业务层自己搭建,应用维护文件哈希和存储对象之间的索引,OSS 负责存放对象,校验和去重的逻辑放在应用里。
判断依据:文件指纹和去重索引
要做到这一点,一般需要下面三样东西。
- 文件指纹:常用 MD5、SHA-256 对文件内容计算哈希。内容差一个字节,结果就完全不同,可以拿来当内容标识。计算时按块读取,不要把整个文件一次性读进内存。
- 去重索引:服务端保存“哈希值到对象地址”的映射。常见做法是在数据库里建一张以哈希为唯一键的表,记录对象 key、文件大小和引用次数。查询走唯一索引,命中与否很快有结果。
- 引用计数:多个用户指向同一个对象时,每多一个引用就加一。删除时只减计数,计数归零才真正删对象。否则一个人删了文件,别人的素材也跟着没了。
阿里云上的两种常见做法
客户端先算哈希,服务端预检
这是最直接的一种。客户端在上传前算好哈希,连同文件名和大小一起提交给业务服务端。服务端查索引,命中就返回已有对象信息,客户端据此完成登记;未命中,再走正常的分片上传。
这种方式几乎不浪费带宽,代价落在客户端。大文件算哈希要花时间,所以需要做分片读取和进度提示,否则界面会像卡住了一样。
借助 OSS 返回的校验值
简单上传时,OSS 返回的 ETag 通常就是对象内容的 MD5,可以直接用来比对。但分片上传的 ETag 计算方式不同,不能当作整文件的 MD5 使用。处理方式有两种:一是在业务侧单独存一份完整文件哈希字段,二是使用 OSS 支持的 CRC64 校验。无论选哪种,入库和比对必须用同一个口径。
上线前建议在测试环境把普通上传和分片上传各跑一遍,看看 ETag 实际返回什么,再写比对逻辑。这一步如果省掉,后面很容易出现内容一样却判不中,或者内容不同却被误判为相同的情况。
一个设计团队的改造记录
某设计团队的素材库每月新增约两万个文件,其中不少是同一批字体包、模板工程和视频片段,被不同成员反复上传。改造前,存储成本逐月上升,大文件上传也常被抱怨太慢。
他们在上传组件里加入了客户端哈希计算,服务端以 SHA-256 作为去重表的键,命中的对象直接增加引用计数。上线一个月后,统计显示重复文件约占 30%,这部分几乎瞬时完成,存储占用也随之下降。删除逻辑同步调整:引用归零后不立即删除,而是交给延迟清理任务执行,留出缓冲,避免误删仍在使用的素材。
这个 30% 来自该团队自身的业务结构,不能直接套用到别的场景。素材复用率高的团队收益最明显;如果主要是日志类文件,每份内容都不同,秒传几乎没有用处,这时把精力放在压缩和生命周期策略上更划算。
落地时要注意的几件事
- 哈希算法选型:MD5 已有公开的碰撞案例,对安全有要求的场景直接使用 SHA-256。
- 权限按逻辑文件控制:多个用户共享同一物理对象,访问校验必须落在“这个用户能不能读这个文件”上。如果只校验对象地址,拿到地址的人就可能越权读取。
- 异常要有对账:上传中途断开、索引写入成功但对象没有完整落盘,这类情况迟早会遇到。定期比对索引和 OSS 实际对象,发现不一致时补偿或报警。
- 控制客户端计算压力:哈希使用流式计算,并限制同时计算的文件数,避免客户端机器被拖慢。
总结
秒传的做法,是用内容指纹替代重复传输。在阿里云 OSS 上,它是一套业务设计,控制台里没有对应的按钮。动手前先看看自己文件的复用率,再决定哈希算法、索引结构和权限模型。