成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

性能炸裂!Spring Boot 3.4 + ThreadPoolTaskExecutor 批量插入百萬數據!

開發 前端
在高并發、大數據量插入的場景下,傳統的 單線程批量插入 方式已經無法滿足性能需求。通過 Spring Boot 3.4 + ThreadPoolTaskExecutor,我們可以充分利用 多線程并發處理,顯著提升數據庫寫入性能。

在現代應用場景中,批量數據處理已經成為影響系統性能的關鍵因素之一。尤其是在大規模數據插入的過程中,傳統的單線程方式往往難以滿足高效數據處理的需求。本文將基于 Spring Boot 3.4 版本,結合 ThreadPoolTaskExecutor 線程池技術,實現 多線程批量插入300萬條數據,并進行性能實測。我們將詳細剖析 MyBatis-Plus 結合 Spring 異步任務 的最佳實踐,提供完整的代碼示例,確保數據的高效存儲和一致性。

方案概述

開發目的

提升大規模數據插入的效率,減少數據庫壓力,提高整體性能。

采用方案

利用 Spring Boot 3.4 結合 ThreadPoolTaskExecutor,使數據插入任務并發執行,提高數據庫寫入吞吐量。

技術棧

  • Spring Boot 3.4
  • MyBatis-Plus
  • Swagger
  • Lombok
  • MySQL
  • ThreadPoolTaskExecutor

線程池配置

# 核心線程數
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 配

package com.icoderoad.config;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;


import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;


@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("啟動線程池 asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix(namePrefix);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

異步任務執行

package com.icoderoad.service.impl;


import com.icoderoad.mapper.LogOutputResultMapper;
import com.icoderoad.model.LogOutputResult;
import com.icoderoad.service.AsyncService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;


import java.util.List;
import java.util.concurrent.CountDownLatch;


@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {
    @Override
    @Async("asyncServiceExecutor")
    public void executeAsync(List<LogOutputResult> logOutputResults, LogOutputResultMapper logOutputResultMapper, CountDownLatch countDownLatch) {
        try {
            log.warn("執行異步插入任務");
            logOutputResultMapper.addLogOutputResultBatch(logOutputResults);
        } finally {
            countDownLatch.countDown();
        }
    }
}

業務調用多線程插入

package com.icoderoad.service.impl;


import com.icoderoad.mapper.LogOutputResultMapper;
import com.icoderoad.model.LogOutputResult;
import com.icoderoad.service.AsyncService;
import com.icoderoad.utils.ConvertHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;


import java.util.List;
import java.util.concurrent.CountDownLatch;


@Slf4j
@Service
public class LogOutputService {
    private final AsyncService asyncService;
    private final LogOutputResultMapper logOutputResultMapper;


    public LogOutputService(AsyncService asyncService, LogOutputResultMapper logOutputResultMapper) {
        this.asyncService = asyncService;
        this.logOutputResultMapper = logOutputResultMapper;
    }


    public int testMultiThread() {
        List<LogOutputResult> logOutputResults = getTestData();
        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();
    }


    private List<LogOutputResult> getTestData() {
        return ConvertHandler.generateTestData(3000000);
    }
}

工具類 ConvertHandler

package com.icoderoad.utils;


import com.icoderoad.model.LogOutputResult;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


public class ConvertHandler {
    public static <T> List<List<T>> splitList(List<T> list, int size) {
        List<List<T>> parts = new ArrayList<>();
        for (int i = 0; i < list.size(); i += size) {
            parts.add(new ArrayList<>(list.subList(i, Math.min(list.size(), i + size))));
        }
        return parts;
    }


    public static List<LogOutputResult> generateTestData(int count) {
        return IntStream.range(0, count)
                .mapToObj(i -> new LogOutputResult((long) i, "TestLog " + i))
                .collect(Collectors.toList());
    }
}

數據訪問層 LogOutputResultMapper

package com.icoderoad.mapper;


import com.icoderoad.model.LogOutputResult;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;


@Mapper
public interface LogOutputResultMapper {
    @Insert("INSERT INTO log_output_result (id, message) VALUES (#{id}, #{message})")
    void addLogOutputResultBatch(List<LogOutputResult> logOutputResults);
}

測試結果

  • 單線程 
    插入 300萬 數據,耗時 5.75分鐘
  • 30個線程 
    并發插入 300萬 數據,耗時 1.67分鐘,效率提升 3.4倍
  • 數據完整性檢查無誤,無重復數據。

結論

在高并發、大數據量插入的場景下,傳統的 單線程批量插入 方式已經無法滿足性能需求。通過 Spring Boot 3.4 + ThreadPoolTaskExecutor,我們可以充分利用 多線程并發處理,顯著提升數據庫寫入性能。在本次實驗中,我們成功地將 300 萬數據的插入時間 從 8.62 分鐘縮短到 2.50 分鐘多線程(30 線程)耗時約:2.50 分鐘,單線程耗時約:8.62 分鐘。

此外,我們通過 SQL 語句檢查 數據完整性,確保所有數據均成功寫入且無重復問題。由此可見,采用 ThreadPoolTaskExecutor 進行多線程優化 是提升大數據量插入效率的有效方案,適用于 日志存儲、批量數據導入、業務數據初始化 等場景。

未來,我們可以進一步優化方案,例如:

  • 動態調整線程池大小,以適應不同負載的插入任務。
  • 異步批量提交事務,減少數據庫鎖競爭,提高吞吐量。
  • 結合 Kafka / RabbitMQ 進行異步解耦,進一步優化數據處理架構。

總的來說,合理使用 Spring 線程池技術,可以大幅度提升應用的性能,優化數據處理的效率,為企業級系統帶來顯著的收益!


責任編輯:武曉燕 來源: 路條編程
相關推薦

2024-07-31 09:56:20

2025-03-31 01:22:00

2020-11-23 10:50:27

MySQLSQL數據庫

2013-09-22 10:25:23

MySQLSQL性能優化

2013-04-01 15:03:58

Android開發Android批量插入

2025-03-03 08:00:00

SpringBootEasyExcel數據導出

2024-12-03 10:46:48

Spring優化開發

2025-05-28 05:10:00

策略Spring性能

2025-06-24 08:15:00

R edis線程數據庫

2018-08-09 08:59:56

數據庫MySQL性能優化

2025-03-13 00:25:00

SpringJava瀏覽器

2025-04-27 01:55:44

SpringConfigData配置

2025-04-29 07:44:26

配置校驗機制

2021-04-08 10:55:53

MySQL數據庫代碼

2024-08-05 09:51:00

2025-05-12 00:00:00

2012-11-23 10:00:55

SQL性能測試

2025-05-20 09:31:19

2025-03-27 08:10:19

Spring開發架構

2011-08-04 18:00:47

SQLite數據庫批量數據
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久小视频 | 亚洲一区 中文字幕 | 中文字幕在线精品 | 欧美日韩a | 午夜视频免费在线 | 欧美成人精品在线 | 久久亚洲一区二区三区四区 | 欧洲成人午夜免费大片 | 95国产精品 | 亚洲a在线视频 | 精品二三区 | 亚洲国产自产 | 欧美亚洲视频在线观看 | 久久久国产一区二区三区 | 精品一区二区三区免费视频 | 岛国在线免费观看 | 欧美另类视频在线 | 欧美日韩中文字幕 | 狠狠操av | 国产精品成人国产乱一区 | 妹子干综合 | 国产极品粉嫩美女呻吟在线看人 | 91视频在线观看 | www网站在线观看 | 国产亚洲一区二区三区在线观看 | 一区二区视频 | 久久精品国产一区 | 中文字幕一区二区三区乱码在线 | 日韩三级电影在线看 | 日韩欧美视频 | 视频在线一区二区 | 日本不卡免费新一二三区 | 中文字幕一二三区 | 国产日韩欧美另类 | 人操人免费视频 | 久久国产精品免费视频 | 精品免费在线 | 欧美成人a | www.日日夜夜 | 国产乱码精品一区二区三区忘忧草 | 欧美日韩高清一区 |