1、问题说明:最近在做数据统计需求的时候遇到一个瓶颈
假如一个班级对应1000条数据,如果有1000个班级的话,对应100万条数据。需要批量查询并且计算。
2、第一种思路:
2.1、第一步:将1000个班级进行分页处理100个班级分成1页,那么就有10页
对应java代码
List<Integer> classIds = new ArrayList<Integer>();
for (int i = 0; i < 1000; i++) {
classIds.add(i);
}
List<List<Integer>> partition = Lists.partition(classIds, 100);
2.2、第二步使用线程池的方式将数据在每个线程中处理然后建结果汇聚到主线程中在操作
List<Integer> result = new ArrayList<>();
partition.forEach(k -> {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//handlerData(k);在不同线程中执行统计结果计算
//return data;
}, asyncTaskExecutor).exceptionally(e -> {
logger.error("当前线程{},异步执行失败", Thread.currentThread().getName(), e);
throw new RuntimeException("失败");
});
try {
result.add(future.get(20,TimeUnit.SECONDS));
} catch (Exception e) {
logger.error("当前线程{},异步执行失败", Thread.currentThread().getName(), e);
throw new RuntimeException("失败");
}
});
2.3、这种方式适合数据量比较少的时候,如果数据量大,在单个应用程序中会造成内存溢出
3、将每个线程对应到微服务中不同应用中去处理
3.1、这样做的好处利用其他资源一起参与计算,将全部线程处理好的结果返回给主线程再次处理
3.2、如下示例代码
借鉴于spark思路,如果不正确的地方欢迎指正