惟快不破:如何快速处理大量数据

背景

  • 将数百张数据结构相同的表(用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。若是数据库的写入速度容许,可适当增长消费进程数量。