聊一聊數據導出那些事

前言

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

對於這個需求,不少系統會做限制,只能從系統導出幾千或幾萬的數據,再多的話就要提申請,經過層層審批,到 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. 查詢導出申請並下載

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

寫在最後

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章