一次大量数据更新的性能优化调研

问题 工作中需要同步一些数据,大概接近百万条的量级,更新时间非常慢,需要7个多小时,更新的频率是每周一次。随着数据量的一步步增加,时间也越来越多,逐渐成为一个风险因子,于是想到要尝试做一些优化,降低同步时间。
分析 经过调查,需要同步的是TABLE_A,同步的过程可以简化表述为两步:

  1. Call API_B to get updated value.
  2. Update records in DB.
首先,检查log,看看这两个过程分别耗时多少。分析生产环境的log,发现,对于一条数据,
  • API call costs: ~350ms.
  • DB update costs: ~20ms.
做一个计算,100万条数据,假设每条同步需要0.4s,那么总耗时就是100h,和实际的6h不符。经过思考后解释是:还需要考虑线程和冗余数据。
实际使用了一个大小为10的线程池,100h除以10的话,就是10h,再算上一些冗余的不需要更新的数据(估计20%左右),理论计算时间和实际时间是在一个数量级上的。
所以,可以从两个方面着手优化,一是优化调用API的时间,二是优化DB写数据的时间。
解决 - API 分析API调用的代码,看到是一条一条调用的,使用了Object callAPI(Object input)这个函数。首先,做一个压力测试,看下callAPI()这个方法每秒可以处理多少请求。
ExecutorService executor = Executors.newFixedThreadPool(100); for (int i=0; i<100; i++) { executor.submit(() -> log.info(callAPI(input))); }

开100个线程,每个线程请求100次,总计10000个request。根据总耗时,计算出callAPI()可以处理请求约50个/秒。这个速度显然已经满足不了我们的系统了。
联系上游API开发部门,经过协商,短期来看,可以为我们配置单独的机器来提高生产环境的query速度。从长远来看,