聊一聊資料匯出那些事

Catcher8發表於2021-04-12

前言

資料匯出,這可以說是一個隨處可見的需求,大部分管理平臺,報表系統都會有這個需求。

對於這個需求,不少系統會做限制,只能從系統匯出幾千或幾萬的資料,再多的話就要提申請,經過層層審批,到 DB 那邊的團隊處理。

其實走不走申請,很大程度上是取決於公司的規章制度,大部分應該還是沒有特別完善的,都是做在系統裡,有許可權的可以匯出所有資料。

說實話,老黃也一直沒搞懂,為什麼有些人老是想著匯出幾十萬,幾百萬的資料在那裡看,過濾,篩選。。。

不過有需求,終究還是要滿足的,像下面這種幾百 MB 的 CSV 檔案,是很經常看的見的。。。

常見問題

匯出大檔案時,一般都會遇到 頻寬記憶體 的問題。

頻寬

如果說,供下載的檔案,是放在我們的伺服器上面,那麼下載的時候是會佔用我們的流出頻寬。

這個在頻寬比較小的情況下是很容易佔滿。

針對頻寬問題,最好的辦法就是不佔用業務系統的頻寬,這個需要引入第三方雲端儲存,比如阿里雲的 OSS,騰訊雲的COS。這樣提供的下載連結是雲端儲存的連結,這樣就和業務系統隔離了。

記憶體

在生成檔案時,如果沒有考慮到記憶體的情況,一次性把資料放到記憶體裡面,就很容易佔用大量的伺服器記憶體。

不限制站點佔用的記憶體,很容易影響伺服器上面的其他站點。

限制了站點佔用的記憶體,容易達到限制引發站點重啟,從而影響正常的訪問。

針對記憶體問題,就是避免一次性把資料全部都放在記憶體裡面,可以分批處理。

下面再來看看一個具體的資料匯出方案。

具體方案

這個方案會有有 5 個角色參與,使用者,後臺系統,中介軟體,匯出系統和雲端儲存。

大體如下圖所示:

這裡老黃把它粗略的分解成10個步驟。

1. 提交匯出申請

使用者想匯出某些內容的時候,需要在後臺系統裡面提交申請。

2. 生成匯出批次

後臺系統接收到使用者提交的申請後,給這個申請生成一個批次號,同時把匯出什麼內容,什麼查詢條件記錄下來。

內容這一個可以儲存查詢的方法名,查詢條件可以儲存方法引數的 JSON 字串。

這樣在匯出資料那一步時可以通過反射處理。

當然還少不了時間,人,狀態這些基本資訊了。

把這些資訊入庫,這一步就算 OK 了。

3. 傳送匯出批次到中介軟體

這一步涉及到中介軟體的選取問題,一般會建議選擇 MQ 或 Redis。

傳送的內容最簡單的就是一個批次號就可以了,當然想把批次的其他資訊組裝一起發過去也是 OK 的。

4. 提交申請成功

當批次資訊成功傳送到中介軟體後,就可以認為系統已經接收了這個申請,這個時候就可以提示使用者申請成功了。

5. 讀取匯出批次資訊

匯出系統這一塊其實還是有很多設計的點的。匯出系統這一塊最好是能獨立伺服器部署,避免對應用伺服器產生級聯影響。

匯出系統要監聽中介軟體裡面的批次資訊,當收到批次資訊後,它就要開始幹活了。這個活分兩類:

一類是,如果這個匯出系統是 中心樞紐,只負責 排程 的話,它的活就是分配給具體的 worker 節點去執行後續的操作,好比建立一個 k8s 的任務。

另一類是,這個匯出系統就是一個 worker 節點,就是負責執行後續內容的。

如果匯出任務不是很頻繁的話,匯出系統 === worker 節點就可以了,也不要過度設計。

6. 查詢/生成/加密檔案

這一步才是真正的執行匯出的操作。

有了批次資訊就可以知道使用者要匯出什麼東西,根據這個就去執行查詢操作,然後把查詢的結果生成對應格式的檔案。

因為所有的檔案,後面都是要上傳到雲端儲存,安全起見的話,需要加一個密碼,避免所有人下載後都能開啟。

檔案有可能不是隻生成一個,可能會按天按月切分,所以最好把檔案放進壓縮包裡面。

這樣在雲端儲存上面都是帶密碼的壓縮包。

7. 上傳到雲端儲存

生成好檔案後,就需要把檔案上傳到雲端儲存裡面。這裡建議有條件的要走內網去上傳,不然 NAT 閘道器或伺服器的頻寬容易打滿。

8. 組裝下載地址

上傳成功後要根據引數拼接好這個檔案的下載地址。

拿到下載地址後,還需要進行有效期處理,即這個下載地址會包含著它的過期時間,什麼時間之後就不能再訪問了。相關雲端儲存都提供了對應的方法,所以這一步會比較簡單。

一般來說,一個檔案會保留 3 ~ 7 天左右的有效期,更久的話就是一個月了。不排除有土豪公司永久儲存。

設定有效期主要有幾個考慮

業務上,不可避免在短時間內會有人匯出相同內容,在有效期範圍內可以複用這一個,避免重複生成。

資源上,雲端儲存的價格,雖然不會特別貴,但還是要省著點,會定期清理一些不需要的歷史檔案

9. 回填資訊

這一步其實就是把處理之後的下載地址、完成時間、批次狀態等資訊更新回批次資訊裡面

10. 查詢匯出申請並下載

到這一步之後,使用者一般會收到站內信,告訴使用者已經可以進行下載操作了,當使用者點下載的時候,跳到雲端儲存的地址,等待下載完成就可以了。

寫在最後

資料匯出,雖然說是一個相對不那麼起眼的功能,但想做到比較好的體驗,也是要花點心思弄一弄的。

這裡介紹的這個方案是實際在用的了,不過只列出了比較粗的內容,還有一些細節內容就不再展開了,好比同一個使用者連續匯出相同的內容等等。

相關文章