惟快不破:如何快速處理大量數據

背景

  • 將數百張數據結構相同的表(用Tn表明),合併至一張表(用C表明)
  • T表數據量分佈很不均衡,少至一位數,多至幾十萬
  • T表間沒有業務關聯
  • C表結構在T表結構的基礎上增長了幾個字段,沒法使用INSERT INTO (SELECT * FROM)
  • 數據總量約300萬,經單進程測試,處理速度約500/s,預估耗時約100min

目標

最大化提高數據處理速度,將耗時降至10min左右,此時C表的寫入速度約5000/s。數據庫

方案演進

方案一

由於T表間沒有業務關聯,因此每張表均可以單獨處理。數據結構

將T表按數據量排序,每一個進程處理N張表,儘可能平衡各進程的負載。負載均衡

存在的問題:T表的數據量分佈極爲不均衡,有幾張表數據量在70萬左右,最終耗時約爲(70萬/500)s,瓶頸問題嚴重。測試

方案二

方案一 的的基礎上,以 表+數據 的維度作並行處理,能夠解決大表瓶頸問題。大數據

存在的問題:代碼實現較複雜,須要考慮排序

  • 每張T表的數據量
  • 對大數據量的T表進行分割
  • 避免數據重複處理

方案三

藉助 Redis 的 pub/sub 機制,實現生產和消費的分離。進程

  • 生產端負責將T表的 表名+ID 均衡發佈至不一樣的channel,channel數量和進程數一致。
  • 消費端每一個進程訂閱不一樣的channel,讀取表名+ID,將表名+ID對應的數據寫入C表。

方案四

方案三的變體,藉助 Redis 的 List,實現生產和消費的分離。同步

  • 生產端負責將T表的 表名+ID 寫入List
  • 消費端讀取List,將 表名+ID 對應的數據寫入C表。

本方案相比 方案三 的優點在於代碼邏輯比較簡潔,生產端和消費端均不須要作負載均衡。消費端能者多勞,多個消費進程同步完成做業。class

實現細節

最終採用方案四基礎

生產端

依次讀取T表數據,將 表名+ID 寫入List。須要注意List支持批量寫入,每次寫入100條數據,寫入速度約50000/s。

消費端

單個進程的消費速度約300/s,起10個消費進程,處理速度能夠達到約3000/s。若是數據庫的寫入速度容許,可適當增長消費進程數量。

相關文章
相關標籤/搜索