1. 程式人生 > >關於大表資料匯出方案設想

關於大表資料匯出方案設想

本方案和需求都是本人設想僅代表個人觀點,沒有實際開發過,肯定有很多細節需要推敲,這裡針對粗劣的需求提供解決方案。實際使用還請看實際需求和相關資源情況。

背景

   很多時候我們需要系統做表格匯出的功能,excel或csv,或記事本等等功能需求。本質上這種情況是我們產品功能不完善或不被信任或沒有挖掘使用者真正需求或很難針對性個性開發的表現。

   這樣就出現了資料匯出的需求,但是對於一個很大的表有著幾百萬上千萬資料的表中如何將資料有格式的匯出到檔案中那?

 

   其中這有幾個比較棘手的問題:

  1.  資料量大,查詢條件多
  2. 要求匯出資料多一般幾萬條或是十幾萬條資料
  3. 一般常規匯出方式耗記憶體和長時間佔用資料庫資源導致業務操作緩慢           

   當然這種資料匯出業務上也有幾個特點:

  1. 即時性要求低,肯定都是匯出前一段時間的資料,用來做必要的特殊分析
  2. 第一點提到的一般這種資料都是以時間為最基本的切分維度

   根據上面的幾點情況分析我們需要實現的匯出功能要對業務要求的即時性和技術處理可實現度達成一個有效的平衡。

方案

    針對上面的需求我們要實現一個折中的方案,也就是說我們既要滿足使用者需求,同時也要儘量小的造成系統(包括資料庫)壓力。

    折中方案一般是客戶提前預約匯出資料請求,系統非同步後臺匯出。

    具體方案先看如下圖示:

 

具體方案說明:

1. 首先建立兩張表,一張是匯出資料表(這個表一般是訂單表等業務主表),另一張是新建的任務表
  • 匯出資料表就是存在各種欄位,資料量比較龐大
  • 任務表就是使用者的預約期望表,其中包含需要的資料的查詢條件,起始和結束時間是必須的,然後還有一些就是針對使用者自己的篩選條件,期望獲取時間等(任務表不一定需要在前臺展示給使用者,或者明確的要求使用者填寫,我們可以在主表查詢介面的“匯出
    ”按鈕作為插入任務表的資料)
2. 資料匯出服務設計
  • 由於我們的需求一般都是有規律的,比如一天一次,一個月一次,一週一次等,這樣我們就需要針對任務表的設定來定時處理(quartz是個不錯的選擇)
  • 我們是針對任務來讀取相關資料,匯出檔案形式的資料。如果針對一個使用者開啟一個執行緒來處理匯出資料就基本夠用了
  • 如果在一張表中有多個使用者,他們需要的資料都是不同要求的,這時我們具體實現的難點
    • 我們可以將一週或一個月的資料分批讀取出來,怎麼分批那?
    • 通過開始和結束時間獲取自增ID的最大和最小值
    • 有了最大和最小值我們按實際情況進行ID分批讀取(這裡我們讀取的是全量資料哦!!)。
    • 將資料讀取到處理程式,進行分類篩選,而不是在資料庫中進行篩選。
    • 將篩選的資料根據使用者任務表進行分類寫入下載檔案
    • 分批次迴圈(看實際情況設定迴圈是否需要間歇給資料庫減輕壓力),對下載檔案進行增量寫
    • 任務表中不斷更新寫入行數作為進度檢視
    • 當資料匯出完成的時候在任務表中列出下載檔案的連結提供下載
  • 這樣的話我們就避免一次查詢數量過大導致記憶體不夠用的情況,同時減輕資料庫瞬時壓力。
  • 通過自增ID(主鍵索引)的方式獲取一個數字之間的資料對於mysql來說非常快,因為mysql資料和主鍵索引是儲存在一起的(InnoDB)這樣我們取資料比較快
3. 方案實現難點及特點
  • 方案實現關鍵在於讀取資料本地記憶體篩選狀態回寫一系列操作的連續性與擴充套件性實現
  • 分段讀取資料讀取速度比較快
  • 我們可以將程式抽象成讀取資料、資料篩選、資料轉化、增量寫檔案,狀態回寫等幾個大塊進行業務解耦。
  • 資料讀取和資料篩選可以單執行緒同步進行
  • 資料轉化和增量寫檔案可以丟到另外的執行緒執行
  • 對檔案增量寫資料操作要注意細節
4. 方案缺點
  • 即時性不是很好(為了折中業務與技術)
  • 在大批量讀取資料的時候如果中間讀取出現問題,要有對應的方案解決
    • 假如我要讀取10000條資料第5批次(每批次1000)失敗了並且已經寫入了500另外500條失敗沒有寫入檔案
    • 這個時候我們需要記錄狀態值來解決這個問題,從記錄的狀態值開始繼續讀取與寫入
    • 如果狀態值沒有寫成功或者寫檔案資料與寫狀態值沒有完成一個原子操作就不可避免的造成一致性的問題
    • 造成上面一致性的問題,我們就需要在匯出檔案中讀取最後一條寫入的資料獲取對應的比較資訊或重複寫入交給客戶篩選處理(交給客戶處理影響客戶體驗

本方案和需求都是本人設想僅代表個人觀點,沒有實際開發過,肯定有很多細節需要推敲,這裡針對粗劣的需求提供解決方案。實際使用還請看實際需求和相關資源情況。