js+php大文件分片上传
1 背景
用户本地有一份txt或者csv文件,无论是从业务数据库导出、还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工、挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通过浏览器上传至服务器,做一层中转便可以实现,但当这份文件非常大到了10GB级别,我们就需要思考另一种形式的技术方案了,也就是本文要阐述的方案。
技术要求主要有以下几方面:
支持超大数据量、10G级别以上
稳定性:除网络异常情况100%成功
准确性:数据无丢失,读写准确性100%
效率:1G文件分钟级、10G文件小时级
体验:实时进度感知、网络异常断点续传、定制字符特殊处理
2 文件上传选型
文件上传至ODPS基本思路是先文件上传至某中转区域存储,然后同步至ODPS,根据存储介质可以分为两类,一类是应用服务器磁盘,另一类类是中间介质,OSS作为阿里云推荐的海量、安全低成本云存储服务,并且有丰富的API支持,成为中间介质的首选。而文件上传至OSS又分为web直传和sdk上传两种方案,因此上传方案有如下三种,详细优缺点对比如下:
蚂蚁的文本上传功能演进过程中对第一种、第二种方案均有实践,缺点比较明显,如上表所述,不满足业务需求,因此大文件上传终极方案是方案三。
3 整体方案
以下是方案三的整体过程示意图。
请求步骤如下:
用户向应用服务器取到上传policy和回调设置。
应用服务器返回上传policy和回调。
用户直接向OSS发送文件上传请求。
等文件数据上传完,OSS给用户Response前,OSS会根据用户的回调设置,请求用户的服务器。如果应用服务器返回成功,那么就返回用户成功,如果应用服务器返回失败,那么OSS也返回给用户失败。这样确保了用户上传成功,应用服务器已经收到通知了。应用服务器给OSS返回。
OSS将应用服务器返回的内容返回给用户。
启动后台同步引擎执行oss到odps的数据同步。
同步实时进度返回返回给应用服务器,同时展示给用户。
4 技术方案
4.1 上传
OSS提供了丰富的SDK,有简单上传、表单上传、断点续传等等,对于超大文件提供的上传功能建议采用断点续传方式,优点是可以对大文件并行分片上传,利用OSS的并行处理能力,中间暂停也可以从当前位置继续上传,网络环境影响可以降到最低。
4.2 下载
OSS文件下载同样也有多种方式,普通下载、流式下载、断点续传下载、范围下载等等,若直接下载到本地同样建议断点续传下载,但我们的需求并不仅仅是下载文件本地存储,而是读取文件做数据从OSS到ODPS的同步,因此不做中间存储,直接边读变写,一方面采用OSS流式读取,一方面ODPS tunnel上传,用多线程读写方式提高同步速率。
4.3 两阶段数据转移
文件从本地到ODPS可以分为两个阶段,第一阶段前端分片断点续传将本地文件上传至OSS,第二阶段后端流式读写将数据从OSS同步至ODPS,如下图所示:
涉及技术点:
4.3.1 前端,js sdk带STS token 安全上传
在需要上传的文件较大时,可以通过multipartUpload接口进行分片上传。分片上传的好处是将一个大请求分成多个小请求来执行,这样当其中一些请求失败后,不需要重新上传整个文件,而只需要上传失败的分片就可以了。一般对于大于100MB的文件,建议采用分片上传的方法,每次进行分片上传都建议重新new一个新的OSS实例。
阿里云分片上传流程主要会调用3个api,包含
InitiateMultipartUpload, 分片任务初始化接口。
UploadPart, 单独的分片上传接口。
CompleteMultipartUpload, 分片上传完成后任务完成接口
临时访问凭证是通过阿里云Security Token Service(STS)来实现授权的一种方式。其实现请参见STS Java SDK。临时访问凭证的流程如下:
客户端向服务器端发起获得授权的请求。服务器端先验证客户端的合法性。如果是合法客户端,那么服务器端会使用自己的AccessKey来向STS发起一个请求授权的请求,具体可以参考访问控制。
服务器端获取临时凭证之后返回给客户端。
客户端使用获取的临时凭证来发起向OSS的上传请求,更详细的请求构造可以参考临时授权访问。客户端可以缓存该凭证用来上传,直到凭证失效再向服务器端请求新的凭证。
4.3.2 后端,多线程流式读写
OSS端:如果要下载的文件太大,或者一次性下载耗时太长,可以多线程流式下载,一次处理部分内容,直到完成文件的下载。
ODPS端:tunnel sdk对OSS流式数据直接写入,一次完整的数据写入流程通常包括以下步骤:
先对数据进行划分;
为每个数据块指定 block id,即调用 openRecordWriter(id);
然后用一个或多个线程分别将这些 block 上传上去, 并在某个 block 上传失败以后,需要对整个 block 进行重传;
在所有 block 都上传以后,向服务端提供上传成功的 blockid list 进行校验,即调用 session.commit([1,2,3,…])
而由于服务端对block管理,连接超时等的一些限制,上传过程逻辑变得比较复杂,为了简化上传过程,SDK提供了更高级的一种RecordWriter——TunnelBufferWriter。
5 实现过程及压测
太多了,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/09/%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88/
6 总结
实测结果显示,本文的上传方案实现了第一节提出的几点技术要求,如下:
支持超大数据量、10G级别以上没有任何压力,主要是前端在分片上传设置好分片限额即可(最大10000片,每片最大100G),目前设置每片1M满足10G需求。
稳定性:实测观察网络异常情况较少,文件内容正常情况下100%成功。
准确性:实测数据无丢失,读写准确性100%。
效率:办公网带宽1.5M/s的情况下1G文件分钟级、10G文件小时级,实际速度视用户端的当前网络带宽变化。
体验:实时进度感知、网络异常断点续传、定制字符特殊处理等高级功能可以提升用户体验。
作者:谷壹
链接:https://www.jianshu.com/p/8b2756a2ec60
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
js+php大文件分片上传的更多相关文章
- Node + js实现大文件分片上传基本原理及实践(一)
_ 阅读目录 一:什么是分片上传? 二:理解Blob对象中的slice方法对文件进行分割及其他知识点 三. 使用 spark-md5 生成 md5文件 四. 使用koa+js实现大文件分片上传实践 回 ...
- js实现大文件分片上传的方法
借助js的Blob对象FormData对象可以实现大文件分片上传的功能,关于Blob和FormData的具体使用方法可以到如下地址去查看FormData 对象的使用Blob 对象的使用以下是实现代码, ...
- nodeJs + js 大文件分片上传
简单的文件上传 一.准备文件上传的条件: 1.安装nodejs环境 2.安装vue环境 3.验证环境是否安装成功 二.实现上传步骤 1.前端部分使用 vue-cli 脚手架,搭建一个 demo 版本, ...
- Webuploader 大文件分片上传
百度Webuploader 大文件分片上传(.net接收) 前阵子要做个大文件上传的功能,找来找去发现Webuploader还不错,关于她的介绍我就不再赘述. 动手前,在园子里找到了一篇不错的分片 ...
- java springboot 大文件分片上传处理
参考自:https://blog.csdn.net/u014150463/article/details/74044467 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时 ...
- vue+大文件分片上传
最近公司在使用vue做工程项目,实现大文件分片上传. 网上找了一天,发现网上很多代码都存在很多问题,最后终于找到了一个符合要求的项目. 工程如下: 对项目的大文件上传功能做出分析,怎么实现大文件分片上 ...
- iOS大文件分片上传和断点续传
总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...
- thinkphp+webuploader实现大文件分片上传
大文件分片上传,简单来说就是把大文件切分为小文件,然后再一个一个的上传,到最后由这些小文件再合并成原来的文件 webuploader下载地址及其文档:http://fex.baidu.com/webu ...
- 在React中使用WebUploader实现大文件分片上传的踩坑日记!
前段时间公司项目有个大文件分片上传的需求,项目是用React写的,大文件分片上传这个功能使用了WebUploader这个组件. 具体交互是: 1. 点击上传文件button后出现弹窗,弹窗内有选择文件 ...
随机推荐
- xshell简单配置(文件上传和下载)
1.安装lrzsz 1.1直接安装#yum install lrzsz 1.2sudo命令安装#sudo yum install lrzsz -y检查是否安装成功.#rpm -qa |grep lrz ...
- Pager
jQuery var Pager = function (ops) { this._ops = { count: ops.count || 0, selectedIndex: ops.selected ...
- Scratch少儿编程系列:(七)太阳系八大行星的运转
一.程序说明 本程序用来模拟太阳系八大行星的运转过程. 二.程序流程图 为了更直观的描述上述过程,采用流程图的方式将猜数字的过程进行描述. 还在制作中... 三.制作过程 1. 场景和角色的选择 场景 ...
- Python基础语法之字典
1 字典基础 1.1 字典是无序的对象的集合,通过键来存取,字典的键只能是不可变类型. 1.3 字典的长度可变,异构,任意嵌套. 1.2 python中不可变数据类型包括:数值类型,字符串和元组. 2 ...
- Tensorflow Learning1 模型的保存和恢复
CKPT->pb Demo 解析 tensor name 和 node name 的区别 Pb 的恢复 CKPT->pb tensorflow的模型保存有两种形式: 1. ckpt:可以恢 ...
- kafka学习(四)
集群成员关系 kafka使用Zookeeper 来维护集群成员的信息.每个broker都有一个唯一标识符,这个标识符可以在配置里指定,也可以自动生成.在broker启动的时候,它通过创建临时节点把自己 ...
- win10上安装redis
1.下载安装包: 下载地址: 链接:https://pan.baidu.com/s/1oGPrfQJvFz-fX_KNcTTNUw 提取码:eake 2.在适合的位置创建一个文件夹,并将下载到的压缩包 ...
- 我的第一个Delphi DLL
library dd; { 使用字符串参数或嵌套字符串参数需要在uses子句中包括sharemm单元,并将BorlandMM.dll与您的应用程序一起发布. 否则需要对参数值使用PChar或Short ...
- c# WPF SVG 文件的引用(SharpVectors)
原文:c# WPF SVG 文件的引用(SharpVectors) 阿里巴巴矢量图标库提供了大量的 SVG 图标:https://www.iconfont.cn/ 但是 WPF 本身不支持 SVG 格 ...
- django后台返回html字段会产生XSS防护的解决方式
1.在前端模块里面写 {{ page_str|safe }} 2.在后端 from django.utils.safestring import mark_safe pake_str = mark_ ...