oss多线程 上传_解读阿里云oss-android/ios-sdk 断点续传(多线程)
摘要: oss sdk 斷點續傳功能使用及其相關原理
前言
移動端現狀
隨著移動端設備的硬件水平的不斷提高,如今的cpu,內存等方面都大大的超過了一般的pc電腦,因此在現今的程序中,合理的使用多線程去完成一些事情是非常有必要的。
多線程上傳的好處
進一步占滿網絡資源。
進一步占滿I/O資源。
實現原理
策略
oss有分片上傳的功能,阿里云斷點續傳就是基于分片上傳的幾個api接口進行的封裝,主要由InitiateMultipartUpload,UploadPart,CompleteMultipartUpload,AbortMultipartUpload,ListParts這幾個組成。
流程
細節
斷點續傳是一個大任務,又3部分來完成,分別是獲取uploadId,分片上傳,完成上傳,這一整個連續的步驟統一在一個線程中進行。
獲取uploadId這塊需要先對本地緩存文件進行獲取,如未拿到,就會直接重新生成新的uploadId直接去進行分片上傳,否則會對記錄的id進行之前上傳了多少片進行還原,繼續原來的位置繼續上傳。
分片上傳部分,采用多線程并發上傳機制,目前線程開啟數量最多5條,根據cpu的核數進行判斷,如果核數<5 會采用核數進行配置, 分片的個數最多5000。
完成上傳,對上傳的part進行排序,需要按照自然順序1~n 的順序進行上傳。
文件校驗,通過文件的md5等其他信息進行校驗,分片上傳中每一片也會跟服務器做md5校驗。
進度回調機制,目前進度回調算是最基礎版,目前回調原理是根據每一個分片來回調的,即當分片上傳成功回調一次。
使用方式
在本地持久保存斷點記錄的調用方式:
android:
String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";
File recordDir = new File(recordDirectory);
// 要保證目錄存在,如果不存在則主動創建
if (!recordDir.exists()) {
recordDir.mkdirs();
}
// 創建斷點上傳請求,參數中給出斷點記錄文件的保存位置,需是一個文件夾的絕對路徑
ResumableUploadRequest request
= new ResumableUploadRequest("", "", "", recordDirectory);
// 設置上傳過程回調
request.setProgressCallback(new OSSProgressCallback() {
@Override
public void onProgress(ResumableUploadRequest request
, long currentSize, long totalSize) {
Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
}
});
OSSAsyncTask resumableTask = oss.asyncResumableUpload(request
, new OSSCompletedCallback() {
@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 = ;
resumableUpload.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:];
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編碼方式進行文件正確性校驗,服務端與客戶端進行交互驗證。
分片上傳的多線程數量改為可配置,用戶可以根據自己的實際需求進行設置。
進度回調優化,對進度的粒度進一步的細化,支持回調頻率可配置等。
總結
以上是生活随笔為你收集整理的oss多线程 上传_解读阿里云oss-android/ios-sdk 断点续传(多线程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kotlin sealed 中_7.8
- 下一篇: gossip 区块链_区块链技术创新生态