大文件分步式分片上传和续传

一,应用场景

1,管理后台往往需要上传app包文件,导入大量数据文件等,其文件大小可能会远超过php或nginx的上传限制,为了一个上传功能,在生产环境修改php或nginx的全局配置会牵一发而动全身,不是好的办法,这时就可以使用分片上传的方式来解决。

2,网络超时等原因,导致上传失败,又需要重传,通过分片机制,只需要上传缺失的分片即可。

分片上传,思路是把大文件,按照一定大小,分成多块,分别上传,上传完毕后合并出原始文件。

二,分片上传的优点

1,可以突破php或nginx上传大小限制,理论可以上传无限大数据(当然不能超过服务器的硬盘大小)。

2,可以使用异步或多线程上传来提高上传速度,在javascript中可以使用xmlhttprequest进行异步上传,在PHP中可以使用协程库GuzzleHttp 进行并发上传,其它语言也可以使用多线程的方式上传,还可以开多个浏览器上传,多个同事一块传都可以。

3,断线重传,如果在上传过程中,网络中断,可以在网络恢复后以块大小为单位,进行重传,已经上传的成功的分片就不需要再次上传。

三,服务器架构

1,客户端负责读取大文件,按偏移量分片,并发上传。

2,分步式文件系统,用来存上传的分片,以备合并时拉取。这里以TFS为例

3,Mysql记录原始文件信息,和各分片信息。用于分片检测。

四,上传流程

服务端接口:

接口1,获取缺失分片接口,http://.../upload/getMissBlocks?filename=file1&md5=xxx&fileSize=23423

接口2,上传分片接口,http://.../upload/uploadBlocks?fileId=1&blockId=4&data=...

1,客户端对分件分片

1.1,客户端首先获取本地待上传文件大小,最后修改时间,MD5等信息。

1.2,了解服务器配置情况,最大文件上传限制,假设为5M。

1.3,获取文件在服务端是否已经存在,通过接口1 把文件的大小,md5值发给服务端检测是否已经存在。如果不存在继续检测该文件相关分片是否已经存在。如果存在部分分片,则把缺失分片和服务端的分片规则返回给客户端。

1.4, 客户端分片,假设要上传的文件大小为312M,分片方法为ceil(312/5) = 63片, 每片大小为5M,最后一片大小为2M

1.5, 根据文件偏移量,对分块进行编号,比如0-5M  blockId=1,5-10M  blockId=2

1.6, 发送异步请求执行接口2,客户端将完整文件大小,MD5,  最后修改时间,分块数,当前块ID,当前块大小和内容一并发给服务端。

 (大文件md5会比较慢,为了提升上传前的计算效率,建议只对整包进行一次md5, 分片只获取大小就可以了)

  javascript客户端:可以使用XmlHttpRequest循环异步上传即可

  php或其它语言客户端: 根据线程数或并发数,进行上传任务分配,然后进行并发上传。

2,服务端的合并

2.1,服务端收到分片后,先将分片以文件名+编号为作为分片文件名,保存在分片目录,为了防止相同的文件名冲突 , 可以将目录结构设为/path/blocks/{filename}/{fileMD5}/{filename}_{blockid} ,并将所有的分片大小,序号,和整包的MD5,大小等信息记录下来(redis/mysql)。

2.2,如果客户端是同步,而且分片是顺序上传的,可以每上传一块,就合并一块,但如果是异步并发上传的,千万不要每收到一块就合并一块,因为服务端很可能会先收到第3块,后收到第2块的情况。所以需要先将所有分片先存下来,而只是在服务端进行分片ID计数,等到所有分片上传完成后,再进行合并操作。

2.3,分片合并,合并的时候,按照分片序号逐一检测其大小是否与记录中分片大小相同,如果相同就合并,如果不相同返回错误给客户端,等待后续的重传。全部合并完成后,对合并出来的整包进行md5进行校验,如果相同,则上传成功,否则通知客户端, 上传异常。等待重传。

3,缺失分片检测

客户端在上传前应该先进行分片缺失检测,可以请求服务端接口来获取某个文件所缺失的分片,缺失分片包括,没有上传的或上传不完整的,只需要根据分片上传的记录和分片文件判断即可。

客户端收到返回后,只需将缺失的分片上传即可

4,TFS并发下载

为了更快的下载,可以使用GuzzleHttp库以协程的方法进行并发下载,因为已经是分块了,所以一般都不会很大,所以这里可以不考虑对每个分片再分多块下载,对于大文件更精细化的安全下载,可以参考我的另一篇文章。<<大文件下载断点续传>>

5,注意事项及优化

1,注意客户端上传前的校验,本地文件在服务器端是否一致,如果不一致要全部重传。如果存在部分分片应该检测,服务端分片规则和本地是否一致。

2,注意因为是并发上传,分片到达服务器的顺序不一定是顺序的。大多数情况下最后一片会比平均分片小所以会先传上去,所以不能以最后一片到达的时机触发合并行为。而是应该检查所有分片是否到达.初步检测分片全部存在后,再合并然后再做最后的md5检测。

3,优化,TFS并不适用于1M以上的大文件存储。可以看公司已有资源情况,使用其它文件系统。

 

转载于:https://my.oschina.net/appnet/blog/1591830

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值