springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

2024-03-04 0 4,367

目录

前言

开发目的:提高百万级数据插入效率
采取方案:利用ThreadPoolTaskExecutor多线程批量插入。
采用技术:springboot2.1.1+mybatisPlus3.0.6+swagger2.5.0+Lombok1.18.4+postgresql+ThreadPoolTaskExecutor等。

具体实现细节

application-dev.properties添加线程池配置信息

# 异步线程配置
# 配置核心线程数
async.executor.thread.core_pool_size = 30
# 配置最大线程数
async.executor.thread.max_pool_size = 30
# 配置队列大小
async.executor.thread.queue_capacity = 99988
# 配置线程池中的线程的名称前缀
async.executor.thread.name.prefix = async-importDB-

spring容器注入线程池bean对象

@Configuration
 
@EnableAsync
 
@Slf4j
 
public class ExecutorConfig {
    @Value(\"${async.executor.thread.core_pool_size}\")
    private int corePoolSize;
    @Value(\"${async.executor.thread.max_pool_size}\")
    private int maxPoolSize;
    @Value(\"${async.executor.thread.queue_capacity}\")
    private int queueCapacity;
    @Value(\"${async.executor.thread.name.prefix}\")
    private String namePrefix;
 
    @Bean(name = \"asyncServiceExecutor\")
    public Executor asyncServiceExecutor() {
        log.warn(\"start asyncServiceExecutor\");
        //在这里修改
        ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(corePoolSize);
        //配置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        //配置队列大小
        executor.setQueueCapacity(queueCapacity);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix(namePrefix);
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
}

创建异步线程 业务类

@Service
 
@Slf4j
 
public class AsyncServiceImpl implements AsyncService {
@Override
    @Async(\"asyncServiceExecutor\")
    public void executeAsync(List<LogOutputResult> logOutputResults, LogOutputResultMapper logOutputResultMapper, CountDownLatch countDownLatch) {
        try{
            log.warn(\"start executeAsync\");
            //异步线程要做的事情
            logOutputResultMapper.addLogOutputResultBatch(logOutputResults);
            log.warn(\"end executeAsync\");
        }finally {
            countDownLatch.countDown();// 很关键, 无论上面程序是否异常必须执行countDown,否则await无法释放
        }
    }
}

创建多线程批量插入具体业务方法

@Override
    public int testMultiThread() {
        List<LogOutputResult> logOutputResults = getTestData();
        //测试每100条数据插入开一个线程
        List<List<LogOutputResult>> lists = ConvertHandler.splitList(logOutputResults, 100);
        CountDownLatch countDownLatch = new CountDownLatch(lists.size());
        for (List<LogOutputResult> listSub:lists) {
            asyncService.executeAsync(listSub, logOutputResultMapper,countDownLatch);
        }
        try {
            countDownLatch.await(); //保证之前的所有的线程都执行完成,才会走下面的;
            // 这样就可以在下面拿到所有线程执行完的集合结果
        } catch (Exception e) {
            log.error(\"阻塞异常:\"+e.getMessage());
        }
        return logOutputResults.size();
    }

模拟2000003 条数据进行测试

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

多线程 测试 2000003  耗时如下:耗时1.67分钟

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

本次开启30个线程,截图如下:

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

单线程测试2000003  耗时如下:耗时5.75分钟

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

检查多线程入库的数据,检查是否存在重复入库的问题:

根据id分组,查看是否有id重复的数据,通过sql语句检查,没有发现重复入库的问题

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

检查数据完整性: 通过sql语句查询,多线程录入数据完整

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

测试结果

不同线程数测试:

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

总结

通过以上测试案列,同样是导入2000003  条数据,多线程耗时1.67分钟,单线程耗时5.75分钟。通过对不同线程数的测试,发现不是线程数越多越好,具体多少合适,网上有一个不成文的算法:
CPU核心数量*2 +2 个线程。
附:测试电脑配置

springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 springboot使用ThreadPoolTaskExecutor多线程批量插入百万级数据的实现方法 http://www.20zxx.cn/808740/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务