1 背景

用户本地有一份txt或者csv文件,无论是从业务数据库导出、还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工、挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通过浏览器上传至服务器,做一层中转便可以实现,但当这份文件非常大到了10GB级别,我们就需要思考另一种形式的技术方案了,也就是本文要阐述的方案。

技术要求主要有以下几方面:

  • 支持超大数据量、10G级别以上

  • 稳定性:除网络异常情况100%成功

  • 准确性:数据无丢失,读写准确性100%

  • 效率:1G文件分钟级、10G文件小时级

  • 体验:实时进度感知、网络异常断点续传、定制字符特殊处理

2 文件上传选型

文件上传至ODPS基本思路是先文件上传至某中转区域存储,然后同步至ODPS,根据存储介质可以分为两类,一类是应用服务器磁盘,另一类类是中间介质,OSS作为阿里云推荐的海量、安全低成本云存储服务,并且有丰富的API支持,成为中间介质的首选。而文件上传至OSS又分为web直传和sdk上传两种方案,因此上传方案有如下三种,详细优缺点对比如下:

蚂蚁的文本上传功能演进过程中对第一种、第二种方案均有实践,缺点比较明显,如上表所述,不满足业务需求,因此大文件上传终极方案是方案三。

3 整体方案

以下是方案三的整体过程示意图。

请求步骤如下:

  1. 用户向应用服务器取到上传policy和回调设置。

  2. 应用服务器返回上传policy和回调。

  3. 用户直接向OSS发送文件上传请求。
         等文件数据上传完,OSS给用户Response前,OSS会根据用户的回调设置,请求用户的服务器。如果应用服务器返回成功,那么就返回用户成功,如果应用服务器返回失败,那么OSS也返回给用户失败。这样确保了用户上传成功,应用服务器已经收到通知了。

  4. 应用服务器给OSS返回。

  5. OSS将应用服务器返回的内容返回给用户。

  6. 启动后台同步引擎执行oss到odps的数据同步。

  7. 同步实时进度返回返回给应用服务器,同时展示给用户。

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,包含

  1. InitiateMultipartUpload,      分片任务初始化接口。

  2. UploadPart, 单独的分片上传接口。

  3. CompleteMultipartUpload,      分片上传完成后任务完成接口

临时访问凭证是通过阿里云Security Token Service(STS)来实现授权的一种方式。其实现请参见STS Java SDK。临时访问凭证的流程如下:

  1. 客户端向服务器端发起获得授权的请求。服务器端先验证客户端的合法性。如果是合法客户端,那么服务器端会使用自己的AccessKey来向STS发起一个请求授权的请求,具体可以参考访问控制。

  2. 服务器端获取临时凭证之后返回给客户端。

  3. 客户端使用获取的临时凭证来发起向OSS的上传请求,更详细的请求构造可以参考临时授权访问。客户端可以缓存该凭证用来上传,直到凭证失效再向服务器端请求新的凭证。

4.3.2 后端,多线程流式读写

OSS端:如果要下载的文件太大,或者一次性下载耗时太长,可以多线程流式下载,一次处理部分内容,直到完成文件的下载。
ODPS端:tunnel sdk对OSS流式数据直接写入,一次完整的数据写入流程通常包括以下步骤:
先对数据进行划分;

  1. 为每个数据块指定      block id,即调用 openRecordWriter(id);

  2. 然后用一个或多个线程分别将这些 block 上传上去, 并在某个 block 上传失败以后,需要对整个 block 进行重传;

  3. 在所有 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大文件上传断点续传解决方案的更多相关文章

  1. Web大文件上传断点续传解决方案

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  2. vue大文件上传断点续传解决方案

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  3. .net大文件上传断点续传解决方案

    HTML部分 <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="index.aspx. ...

  4. ASP.NET大文件上传断点续传解决方案

    HTML部分 <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="index.aspx. ...

  5. JAVA大文件上传断点续传解决方案

    javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1.通过form表单向后端发送请求 <form id=" ...

  6. JSP大文件上传断点续传解决方案

    我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 首先我们需要了解的是上传文件三要素: 1.表单提交方式:post (get方式提交有大小 ...

  7. PHP大文件上传断点续传解决方案

    1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...

  8. Asp.net mvc 大文件上传 断点续传

    Asp.net mvc 大文件上传 断点续传 进度条   概述 项目中需要一个上传200M-500M的文件大小的功能,需要断点续传.上传性能稳定.突破asp.net上传限制.一开始看到51CTO上的这 ...

  9. JS大文件上传解决方案

    1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...

随机推荐

  1. C# while循环及for循环,for循环的嵌套,冒泡循环

    循环四要素:初始条件.循环条件.循环体.状态改变 初始条件:开始进入循环 所需要的 第一次条件 循环条件:执行循环所需要满足的条件 循环体:每次循环要执行的代码 状态改变:执行完当前循环体后 循环条件 ...

  2. 2019牛客暑期多校训练营(第二场)-F artition problem

    题目链接:https://ac.nowcoder.com/acm/contest/882/F 题意:将2×n个人分成两组,每组n个人,求一个组中所有人和另外一组的所有人的竞争值之和. 思路: 比赛时看 ...

  3. [Python3] 039 语法调试

    目录 语法调试 1. 调试技术 2. pdb 调试 插一个 gdb 3.Pycharm 调试 4. 单元测试 语法调试 1. 调试技术 调试流程 单元测试 → 集成测试 → 交测试部 分类: 静态调试 ...

  4. mapreduce运行的bug收录

    在8088端口可以看到日志文件(主要看error),操作如下: 1.window jdk版本最好和linux jdk 版本一致,不然容易出现莫名奇妙的bug 之前出现一个bug: Unsupporte ...

  5. ORM中的锁和事务

    锁 sql语句加锁 select * from book where id=1 for update; begin; start transaction; select * from t1 where ...

  6. 基于Keras的OpenAI-gym强化学习的车杆/FlappyBird游戏

    强化学习 课程:Q-Learning强化学习(李宏毅).深度强化学习 强化学习是一种允许你创造能从环境中交互学习的AI Agent的机器学习算法,其通过试错来学习.如上图所示,大脑代表AI Agent ...

  7. zabbix-3.4.6安装

    先安装myql和phpmysql5.7.17: http://www.cnblogs.com/cjsblogs/p/8116782.htmlphp7.2.1: http://www.cnblogs.c ...

  8. Linux(17):Shell编程(4)

    案例1:批量生成随机字 符 文件名案例 使用for 循环在 /neo 目录下批量创建10个html文件,其中每个文件需要包含10个随机小写字母加固定字符串 neo创建的结果名称示例 如下: [root ...

  9. 关于redis的几件小事(七)redis缓存雪崩与穿透

    1.缓存雪崩 (1)什么是缓存雪崩 缓存雪崩指的是在同一时刻,缓存大量失效,导致大量的请求直接到了数据库,数据库压力剧增,引起系统崩溃.可能出现的情况有: ①大量的key设置了相同的过期时间,导致在缓 ...

  10. js之运算符其它运算符(三元运算符,逗号运算符,void运算符,typeof,delete运算符)

    Javascript支持很多其它的运算符,具体如下: 一.条件运算符(?:) 条件运算符是Javascript中唯一的三个操作数的三元运算符,有时会直接称做是“三元运算符”. 基本格式:conditi ...