SpringCloud大檔案分片斷點上傳實現原理

2022-09-27 07:09:11 字數 2966 閱讀 1583

1背景

使用者本地有乙份txt或者csv檔案,無論是從業務資料庫匯出、還是其他途徑獲取,當需要使用螞蟻的大資料分析工具進行資料加工、挖掘和共創應用的時候,首先要將本地檔案上傳至odps,普通的小檔案通過瀏覽器上傳至伺服器,做一層中轉便可以實現,但當這份檔案非常大到了10gb級別,我們就需要思考另一種形式的技術方案了,也就是本文要闡述的方案。

技術要求主要有以下幾方面:

支援超大資料量、10g級別以上

穩定性:除網路異常情況100%成功

準確性:資料無丟失,讀寫準確性100%

效率:1g檔案分鐘級、10g檔案小時級

體驗:實時進度感知、網路異常斷點續傳、定製字元特殊處理

2檔案上傳選型

檔案上傳至odps基本思路是先檔案上傳至某中轉區域儲存,然後同步至odps,根據儲存介質可以分為兩類,一類www.cppcns.com是應用伺服器磁碟,另一類類是中間介質,oss作為阿里雲推薦的海量、安全低成本雲儲存服務,並且有豐富的api支援,成為中間介質的首選。而檔案上傳至oss又分為web直傳和sdk上傳兩種方案,因此上傳方案有如下三種,詳細優缺點對比如下:

螞蟻的文字上傳功能演進過程中對第一種、第二種方案均有實踐,缺點比較明顯,如上表所述,不滿足業務需求,因此大檔案上傳終極方案是方案三。

3整體方案

以下是方案三的整體過程示意圖。

請求步驟如下:

使用者向應用伺服器取到上傳policy和**設定。

應用伺服器返回上傳policy和**。

使用者直接向oss傳送檔案上傳請求。

等檔案資料上傳完,oss給使用者response前,oss會根據使用者的**設定,請求使用者的伺服器。如果應用伺服器返回成功,那麼就返回使用者成功,如果應用伺服器返回失敗,那麼oss也返回給使用者失敗。這樣確保了使用者上傳成功,應用伺服器已經收到通知了。

應用伺服器給oss返回。

ovktiudihsss將應用伺服器返回的內容返回給使用者。

啟動後台同步引擎執行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 j**a 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總結實測結果顯示,本文的上傳方案實現了第一節提出的幾點技術要求,如下:

支援超大資料量、10g級別以上沒有任何壓力,主要是前端在分片上傳設定好分片限額即可(最大10000片,每片最大100g),目前設定每片1m滿足10g需求。

穩定性:實測觀察網路異常情況較少,檔案內容正常情況下100%成功。

準確性:實測資料程式設計客棧無丟失,讀寫準確性100%。

效率:辦公網頻寬1.5m/s的情況下1g檔案分鐘級、10g檔案小時級,實際速度視使用者端的當前網路頻寬變化。

體驗:實時進度感知、網路異常斷點續傳、定製字元特殊處理等高階功能可以提公升使用者體驗。

本文標題: springcloud大檔案分片斷點上傳實現原理

本文位址: /ruanjian/j**a/312689.html

上傳大檔案 關於大檔案上傳

js計算檔案md5使用spark md5.js,據說這個庫使用的是世界上最快的md5演算法。js對檔案切片並使用ajax上傳切片 let size file.size 獲取檔案大小 const shardsize 1024 1024 塊大小1mb let shardcount math.ceil s...

大檔案拆分

fp e logtest u ex160314.log 原檔名稱 fname e logtest u ex160314 新檔名稱 fsize 1024 1024 1mb,定義每個新檔案的大小 num 1 新檔名後 1 sum 0 每個新檔案的當前大小 with open fp,rb as fo fo...

大檔案上傳

首先先要建好幾個檔案 html裡面 1238 9141589 90php裡面 1 2 username post username 3 1 接收前端傳過來的引數 4 ori file name post filename 原始檔案的檔名 5 file files file 6 tmp name fi...