解读阿里云oss-android/ios-sdk 断点续传(多线程)

前言

  • 移动端现状
    随着移动端设备的硬件水平的不断提高,如今的cpu,内存等方面都大大的超过了一般的pc电脑,因此在现今的程序中,合理的使用多线程去完成一些事情是非常有必要的。
  • 多线程上传的好处
    1. 进一步占满网络资源。
    2. 进一步占满I/O资源。

实现原理

  • 策略
    oss有分片上传的功能,阿里云断点续传就是基于分片上传的几个api接口进行的封装,主要由InitiateMultipartUpload,UploadPart,CompleteMultipartUpload,AbortMultipartUpload,ListParts这几个组成。
  • 流程
  • 细节
  1. 断点续传是一个大任务,又3部分来完成,分别是获取uploadId,分片上传,完成上传,这一整个连续的步骤统一在一个线程中进行。
  2. 获取uploadId这块需要先对本地缓存文件进行获取,如未拿到,就会直接重新生成新的uploadId直接去进行分片上传,否则会对记录的id进行之前上传了多少片进行还原,继续原来的位置继续上传。
  3. 分片上传部分,采用多线程并发上传机制,目前线程开启数量最多5条,根据cpu的核数进行判断,如果核数<5 会采用核数进行配置, 分片的个数最多5000。
  4. 完成上传,对上传的part进行排序,需要按照自然顺序1~n 的顺序进行上传。
  5. 文件校验,通过文件的md5等其他信息进行校验,分片上传中每一片也会跟服务器做md5校验。
  6. 进度回调机制,目前进度回调算是最基础版,目前回调原理是根据每一个分片来回调的,即当分片上传成功回调一次。

使用方式

在本地持久保存断点记录的调用方式:

android:

String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 要保证目录存在,如果不存在则主动创建
if (!recordDir.exists()) {
    recordDir.mkdirs();
}
// 创建断点上传请求,参数中给出断点记录文件的保存位置,需是一个文件夹的绝对路径
ResumableUploadRequest request
    = new ResumableUploadRequest("<bucketName>", "<objectKey>", "<uploadFilePath>", recordDirectory);
    // 设置上传过程回调
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request
              , long currentSize, long totalSize) {
         Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
     }
});
OSSAsyncTask resumableTask = oss.asyncResumableUpload(request
    , new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
    @Override
    public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
        Log.d("resumableUpload", "success!");
    }

    @Override
    public void onFailure(ResumableUploadRequest request, ClientException clientExcepion
        , ServiceException serviceException) {
           // 异常处理
    }
});

ios:

// 获得UploadId进行上传,如果任务失败并且可以续传,利用同一个UploadId可以上传同一文件到同一个OSS上的存储对象
OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
resumableUpload.bucketName = <bucketName>;
resumableUpload.objectKey = <objectKey>;
resumableUpload.partSize = 1024 * 1024;
resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
    NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};

resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
resumableUpload.recordDirectoryPath = cachesDir;//记录断点的文件路径
OSSTask * resumeTask = [client resumableUpload:resumableUpload];
[resumeTask continueWithBlock:^id(OSSTask *task) {
    if (task.error) {
       NSLog(@"error: %@", task.error);
       if ([task.error.domain isEqualToString:OSSClientErrorDomain]
         && task.error.code == OSSClientErrorCodeCannotResumeUpload) {
           // 该任务无法续传,需要获取新的uploadId重新上传
       }
     } else {
         NSLog(@"Upload file success");
     }
     return nil;
}];

性能统计

数据分析
android/ios 端的分片上传改为并发后的测试与之前对比,上传分片的网络请求速度  多线程 和 单线程是一样的使用时间,这个主要是取决于带宽速度, 多线程相较于单线程主要是提高了读取文件的io时间。数据如下:

iOS 模拟器测试  
100mb大小文件
1000 part  num  单线程  104.530217s  多线程  54.528591s
100  part  num  单线程  59.306880s  多线程  54.336914s
1.31g 大小文件
100 part  num  单线程  746.775666s  多线程  731.940330s
1000 part  num  单线程  822.866331s  多线程  733.306236s
2000 part  num  单线程  965.428122s  多线程  731.940330s
5000 part  num  单线程  1205.379382s  多线程  732.982330s
android motoXT1085 双核cpu
100mb文件
100 part  num  单线程  70.484s  多线程   53.656s
1000 part num  单线程 104.530217s  多线程54.528591s
1.31g视频文件
135  part num  单线程  869s  多线程  738s
1342 part num  单线程   1079.081s  多线程 732.079s


总体来看比之前有提升,单线程随着片的个数的增加时间耗时越来越高,而多线程下,时间基本是一样的,按照目前默认配置的part size 256kb ,单线程下网络资源与I/O资源都吃满,并发下性能提高平均有30%左右(上传时间减少)

小结

移动端下,网络资源与I/O资源一般都比较紧缺,多线程不会提高网络的总带宽:比如,在跑满某个资源下载策略分配一个连接供给带宽2000Kb/s的时候,本地单线程 能够同时吃满 2000Kb/s,这里就到达了一个峰值;但是如果某个资源连接带宽是2000Kb/s,但是单线程请求带宽 已经达到 2000Kb/s,那么就是本地网络带宽 Block了上传速度,也就是说开再多线程,再多连接也都无济于事;但,如果本地网络带宽 吃完2000Kb/s 的同时还有很多的网络资源剩余,假如还有2000Kb/s的提升空间,那么这时再建立一个连接 将这 2000Kb/s 也吃满,那么此时的速度就可以达到 4000Kb/s,这时提速很明显,I/O资源同理。

后续计划

  • 增加crc64编码方式进行文件正确性校验,服务端与客户端进行交互验证。
  • 分片上传的多线程数量改为可配置,用户可以根据自己的实际需求进行设置。
  • 进度回调优化,对进度的粒度进一步的细化,支持回调频率可配置等。
时间: 2024-09-20 20:42:04

解读阿里云oss-android/ios-sdk 断点续传(多线程)的相关文章

Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例

之前从没接触过Yii,借助的各方资源来做的这个整合阿里云OSS的SDK上传图片实例,如果有不正之处请指出! 前面参照了weinirumo 的介绍,大家可以自行去查看. 好了,下面开始进入主题: 准备工作:需要使用composer执行命令,如果没有安装composer的需要提前安装,参考文档:composer安装流程 1.项目目录结构 我使用的是基础版,只有后台目录,请自行对照自己的项目目录结构,会用到以下的几个目录: 2.在项目根目录下运行cmd命令 3.执行composer命令 切换到中国国内

Laravel中使用阿里云OSS Composer包分享

 这篇文章主要介绍了Laravel中使用阿里云OSS Composer包分享,本文讲解其使用方法,文件下载请前往文件中的github地址,需要的朋友可以参考下     阿里云提供了基于命名空间的 V2 版 SDK,但是文档不是很完整,使用门槛比较高,于是我封装了一个 Composer 包:https://github.com/johnlui/AliyunOSS 安装 将以下内容增加到 composer.json: 代码如下: require: {   "johnlui/aliyun-oss&qu

开源备份工具duplicity支持阿里云OSS后端存储

duplicity简介 duplicity是一款开源的备份工具,使用librsync高效地支持增量备份,节约本地存储空间,同时使用GnuPG加密数据.duplicity能将数据轻松的备份到本地或远端文件共享存储,同时支持各类云存储. 不过官方版本并没有支持阿里云作为后端存储,最近用oss最新的Python SDK oss2支持了duplicity上传阿里云OSS,先实现了一个简单的版本,在本文附件中可以下载到集成了aliyunbackend的duplicity安装包. 适用场景 重要文档数据的打

php版阿里云OSS图片上传类详解_php技巧

本文实例讲述了php版阿里云OSS图片上传类.分享给大家供大家参考,具体如下: 1.阿里云基本函数 /** * 把本地变量的内容到文件 * 简单上传,上传指定变量的内存值作为object的内容 */ public function putObject($imgPath,$object) { $content = file_get_contents($imgPath); // 把当前文件的内容获取到传入文件中 $options = array(); try { $this->ossClient->

自动备份db数据到阿里云OSS例子

运维的都知道,最怕就是数据丢失,其它故障什么都好说,数据没了,那可是要死人的,所以DBA这个岗位在公司都比较重视(可惜我不是),当然薪水也不错,一个合格的DBA要做的事很多,远不止只做数据备份恢复工作(数据备份恢复是最基本基本的了),像调优,数据库设计什么的也都需要参与,甚至在项目立项时就要介入了. 前面说了那么多关于DBA的事,就是简单跟大家铺垫下,告诉大家数据对公司或个人来讲是多么的重要,那既然重要,我们就要备份好它,一般做法都是数据库本机留一个备份,然后再异地备份一份,但是随着目前云成为大

阿里云oss挂载到linux本地文件系统

对象存储 OSS 阿里云对象存储服务 (OSS) 是一种高度可伸缩且安全可靠的云对象存储服务,让您可以存储.备份和归档大量数据.阿里云 OSS 是一种简单易用的服务,让您每秒能处理数百万请求,它还支持大数据.科学与财务分析以及媒体应用. 阿里云是一家全球性云对象存储提供商,让您可以随时随地以高度安全.经济实惠的方式存储.处理和访问数据.阿里云 OSS 为企业提供加密云存储,具有自动数据复制与故障转移功能及高达 99.9% 的服务可用性和数据可靠性,是容灾的理想选择. 对比 阿里云OSS : 好处

利用nc 直观理解阿里云OSS 存储服务

1.本文要说什么 利用nc 直接与阿里云OSS服务器建立TCP 连接,通过输入HTTP 请求头部及数据与OSS进行交互,以此理解阿里云OSS服务的本质及使用阿里云OSS过程中的一些trouble shooting. 2.相关准备工作 一台连上互联网的Linux主机(如果没有可以购买一台阿里云ECS),注册并开通阿里云OSS服务(oss.aliyun.com)并创建一个bucket,本文以青岛的bucket:bucket-example(bucket-example.oss-cn-qingdao.

基于阿里的Node全栈之路(三)利用阿里云OSS实现前后端分离

嘿嘿,上篇文章因为在火车上写的,偷懒了,心存愧疚,还是补发一篇吧! 这次嘞,我们聊聊开发上老生常谈的话题,前后端分离.在文章第一篇里,我用了一张我的架构图,这里我把关于OSS的这部分抽出来. 可以看到这种图上,我的docker是只有restful api的作用,在web端应用,客户访问我的网站的时候,是跳转到OSS上的.没错,没错,在我这里,没有使用类似jsp.asp.ejs这些动态页面.先不说两者的优劣,我这里使用的方案,其实蛮有趣的,而且非常的高效实用!对于中型项目是完全行得通的,大型项目架

Aliyun OSS Nginx proxy module(阿里云OSS Nginx 签名代理模块)

1.此文章主要介绍内容 本文主要介绍如何利用Nginx lua 实现将阿里云OSS存储空间做到同本地磁盘一样使用.核心是利用Nginx lua 对OSS请求进行签名并利用内部跳转将所有访问本地Nginx的请求加上OSS 签名转发给OSS,实现本地Nginx无缝衔接阿里云OSS,存储空间无限扩展,存储成本无限下降,数据安全%99.99...... . 2.本篇文章使用到的一些工具技术及如何学习和获取 1.lua 本文用到的都是一些基本的lua,基本上花半小时阅读下lua的语法就可以轻松理解本文内容

Greenplum insert的性能(单步\批量\copy) - 暨推荐使用gpfdist、阿里云oss外部表并行导入

标签 PostgreSQL , Greenplum , HybridDB for PostgreSQL , insert , copy , 外部表 , oss , gpfdist 背景 Greenplum是一款MPP数据库产品,优势是优良的OLAP性能,支持多节点并行计算,实现PB级数据量的实时分析. 除了分析能力,数据写入吞吐也是Greenplum的重要指标,Greenplum支持从master节点写入,也支持从segment节点并行写入. 从segment并行加载的话,性能是线性提升的,因为