天天看點

唯快不破:如何快速處理大量資料背景目标方案演進實作細節

背景

  • 将數百張資料結構相同的表(用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表。

本方案相比 方案三 的優勢在于代碼邏輯比較簡潔,生産端和消費端均不需要做負載均衡。消費端能者多勞,多個消費程序同步完成作業。

實作細節

最終采用方案四。

生産端

依次讀取T表資料,将表名+ID寫入List。需要注意List支援批量寫入,每次寫入100條資料,寫入速度約50000/s。

消費端

單個程序的消費速度約300/s,起10個消費程序,處理速度可以達到約3000/s。如果資料庫的寫入速度允許,可适當增加消費程序數量。

繼續閱讀