0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SpringBoot利用ThreadPoolTaskExecutor批量插入百万级数据实测!

jf_ro2CN3Fa 来源:CSDN 作者:CSDN 2022-11-16 10:38 次阅读


前言

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

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

具体实现细节

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

> 基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
>
> * 项目地址:
> * 视频教程

# 异步线程配置
# 配置核心线程数
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

publicclassExecutorConfig{
@Value("${async.executor.thread.core_pool_size}")
privateintcorePoolSize;
@Value("${async.executor.thread.max_pool_size}")
privateintmaxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
privateintqueueCapacity;
@Value("${async.executor.thread.name.prefix}")
privateStringnamePrefix;

@Bean(name="asyncServiceExecutor")
publicExecutorasyncServiceExecutor(){
log.warn("startasyncServiceExecutor");
//在这里修改
ThreadPoolTaskExecutorexecutor=newVisiableThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(corePoolSize);
//配置最大线程数
executor.setMaxPoolSize(maxPoolSize);
//配置队列大小
executor.setQueueCapacity(queueCapacity);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix(namePrefix);
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
returnexecutor;
}
}

创建异步线程 业务类

@Service
@Slf4j
publicclassAsyncServiceImplimplementsAsyncService{
@Override
@Async("asyncServiceExecutor")
publicvoidexecuteAsync(ListlogOutputResults,LogOutputResultMapperlogOutputResultMapper,CountDownLatchcountDownLatch){
try{
log.warn("startexecuteAsync");
//异步线程要做的事情
logOutputResultMapper.addLogOutputResultBatch(logOutputResults);
log.warn("endexecuteAsync");
}finally{
countDownLatch.countDown();//很关键,无论上面程序是否异常必须执行countDown,否则await无法释放
}
}
}

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

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

模拟2000003 条数据进行测试

4fc16cce-6555-11ed-8abf-dac502259ad0.png

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

4fe0a918-6555-11ed-8abf-dac502259ad0.png4fe8a71c-6555-11ed-8abf-dac502259ad0.png

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

5003382a-6555-11ed-8abf-dac502259ad0.png

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

502a55e0-6555-11ed-8abf-dac502259ad0.png504a0548-6555-11ed-8abf-dac502259ad0.png

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

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

506e5010-6555-11ed-8abf-dac502259ad0.png

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

50798f48-6555-11ed-8abf-dac502259ad0.png

测试结果

不同线程数测试:

508bc816-6555-11ed-8abf-dac502259ad0.png50969b9c-6555-11ed-8abf-dac502259ad0.png

总结

通过以上测试案列,同样是导入2000003 条数据,多线程耗时1.67分钟,单线程耗时5.75分钟。通过对不同线程数的测试,发现不是线程数越多越好,具体多少合适,网上有一个不成文的算法

CPU核心数量*2 +2 个线程。

附:测试电脑配置

50c32c2a-6555-11ed-8abf-dac502259ad0.png

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SQL
    SQL
    +关注

    关注

    1

    文章

    760

    浏览量

    44082
  • 多线程
    +关注

    关注

    0

    文章

    277

    浏览量

    19923
  • spring
    +关注

    关注

    0

    文章

    338

    浏览量

    14314
  • SpringBoot
    +关注

    关注

    0

    文章

    173

    浏览量

    169

原文标题:性能爆表:SpringBoot利用ThreadPoolTaskExecutor批量插入百万级数据实测!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    企业级数据库的配置和管理要求汇总

    企业级数据库配置需高性能硬件支撑,包括服务器、存储、网络及电源冗余,选用稳定DBMS与操作系统,注重索引与查询优化。管理上,强调数据安全,实施加密、访问控制与审计;确保高可用,配置容错机制与备份恢复;监控调优性能,规划容量与扩展性;追求易用性,简化日常管理与维护,确保
    的头像 发表于 09-27 10:50 172次阅读

    DNA计算机研究取得突破性进展:PB级数据存储与高效处理

    8月29日,科学界传来振奋人心的消息,一项革命性的研究成果为实现全功能DNA计算机奠定了坚实基础。研究团队成功开发出一种创新技术,该技术不仅能在DNA中存储惊人的PB级数据,还能确保这些数据在数千乃至数百万年内保持完好,同时实现
    的头像 发表于 08-29 16:29 462次阅读

    天拓四方:工业级数据采集网关核心功能解析与应用价值

    在数字化转型浪潮中,工业4.0与智能制造的概念日益深入人心,而这一切的基石在于高效、准确的数据采集与处理能力。工业级数据采集网关作为连接现场设备与云端或数据中心的关键桥梁,扮演着至关重要的角色。本文
    的头像 发表于 07-23 16:11 309次阅读

    LPS完成战略性收购 增强数据实践和营销云能力

    对Explora和Eleven Digital的战略性收购,以增强其数据实践和营销云能力。此次收购将加强LPS技术创新及赋能联想AI卓越中心(Center of Excellence)所必需的数据基础,加速企业AI
    的头像 发表于 06-05 11:55 289次阅读
    LPS完成战略性收购 增强<b class='flag-5'>数据实</b>践和营销云能力

    fanuc robot interface V3.0批量读写数据寄存器问题

    labview只能读写机器人单个R数据寄存器,不能批量读取,其他读写IO和坐标都没问题。 调用的方法只能使用getValue和setvalue读写单个,不能批量一次性读写数组
    发表于 06-04 15:43

    滤波器插入损耗怎么测试?测试标准是什么?

    插入损耗是指信号通过滤波器后,输出信号与输入信号之间的功率差距。插入损耗包括共模插入损耗和差模插入损耗两种。插入损耗越小,说明滤波器对输入信
    的头像 发表于 05-13 18:37 1521次阅读
    滤波器<b class='flag-5'>插入</b>损耗怎么测试?测试标准是什么?

    车规级数字功放一体成型电感VSAD0660-3R3M数据手册

    电子发烧友网站提供《车规级数字功放一体成型电感VSAD0660-3R3M数据手册.pdf》资料免费下载
    发表于 03-04 11:38 0次下载

    工业级数据采集通用网关在车间数据采集的应用-天拓四方分享

    数据采集网关是至关重要的。 工业级数据采集通用网关具备数据采集、处理、传输功能的设备,可连接多种工业现场设备,如PLC、传感器、执行器等,实现数据的实时采集、传输。其核心功能包括
    的头像 发表于 01-30 16:15 363次阅读

    labview 队列最前端插入的应用

    起到很多作用。本文将详细介绍LabVIEW队列的应用,特别是在最前端插入数据的情况下。 首先,让我们了解LabVIEW队列的基本概念。队列是一种数据结构,允许在一端插入元素,并在另一端
    的头像 发表于 01-08 11:45 1157次阅读

    插入损耗是什么?回波损耗是什么?影响插入损耗和回波损耗的因素

    插入损耗是什么?回波损耗是什么?影响插入损耗和回波损耗的因素 如何优化光纤连接器损耗? 插入损耗是指信号在光纤连接器中传输过程中的信号衰减。而回波损耗是指在光纤连接器两端之间的反射损耗
    的头像 发表于 12-27 15:17 2354次阅读

    轻量级数据库有哪些类型

    轻量级数据库是指具有小巧、灵活、高效的特点,适用于小规模项目和嵌入式设备的数据库管理系统。下面是对轻量级数据库类型的详细介绍,包括关系型数据库、非关系型
    的头像 发表于 12-20 11:29 1205次阅读

    线路板生产该选大批量还是小批量

    线路板生产该选大批量还是小批量
    的头像 发表于 12-13 17:22 902次阅读

    什么是插入式无线传感器?作用是什么?

    什么是插入式无线传感器?作用是什么? 插入式无线传感器是一种用于监测和收集数据的设备,通常被安装在物体表面或者结构中。这些传感器可以感知和测量各种物理和环境参数,如温度、湿度、压力、声音、光线等等
    的头像 发表于 12-12 15:04 618次阅读

    SpringBoot实现动态切换数据

    最近在做业务需求时,需要从不同的数据库中获取数据然后写入到当前数据库中,因此涉及到切换数据源问题。本来想着使用Mybatis-plus中提供的动态
    的头像 发表于 12-08 10:53 987次阅读
    <b class='flag-5'>SpringBoot</b>实现动态切换<b class='flag-5'>数据</b>源

    根据数据手册配置AD9826的寄存器,示波器实测SDATA引脚输出异常的原因?

    根据数据手册配置AD9826的寄存器,设定工作模式为1-SHA 仿真波形如下 示波器实测SDATA引脚输出 但是输出结果异常 为随机值
    发表于 12-04 08:01