前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 处理百万级别数据量解决方案

Spring Boot 处理百万级别数据量解决方案

作者头像
用户7353950
发布2024-04-16 15:23:41
1930
发布2024-04-16 15:23:41
举报
文章被收录于专栏:IT技术订阅IT技术订阅

Spring Boot 处理百万级别的数据量时,常见的挑战包括内存溢出(OOM)、性能低下、数据库连接管理等问题。以下是一些解决策略和相应的代码示例概要: 1. 导出百万级数据 - 分页查询 + 流式处理: - 使用`ResultSet`的流式API或者JPA/Hibernate的分页查询,逐页读取数据,避免一次性加载所有数据到内存。 // JPA分页查询示例 Pageable pageable = PageRequest.of(pageNumber, pageSize); Page<T> dataPage = repository.findAll(pageable); // JDBC流式查询示例(假设使用JdbcTemplate) jdbcTemplate.query(sql, (rs, rowNum) -> { // 处理每一行数据,立即写出到OutputStream或Writer // 不积累在内存中 }, params...);

- 响应式流(Reactive Streams): - 如果使用R2DBC等响应式数据库驱动,可以利用其流式特性处理大数据。 - 服务端生成流式下载: 在Controller层返回`StreamingResponseBody`,边生成CSV或Excel边发送到客户端,不存储中间文件。 @GetMapping(value = "/export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public ResponseEntity<StreamingResponseBody> exportData() { StreamingResponseBody stream = out -> { // 使用writer将数据一行行写入out,同时响应给客户端 try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out))) { // 这里调用分页查询并逐行写出数据 } }; return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=data.csv") .body(stream); } 2. 批量插入百万级数据 - 批量插入: - 使用JDBC的BatchUpdate API,或者JPA的`saveAll()`方法进行批量插入。 // JDBC批量插入示例 jdbcTemplate.batchUpdate( "INSERT INTO table_name (col1, col2) VALUES (?, ?)", new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setString(1, value1[i]); ps.setString(2, value2[i]); } @Override public int getBatchSize() { return values.length; } }); // JPA批量插入示例 List<MyEntity> entities = ... // 构建百万级实体列表 repository.saveAll(entities); - 异步处理 + 线程池: - 利用`ThreadPoolTaskExecutor`分批次提交任务,分散压力。 @Autowired private ThreadPoolTaskExecutor executor; public void batchInsert(List<MyEntity> dataList) { int batchSize = 5000; // 根据实际数据库承受能力调整 List<List<MyEntity>> partitions = Lists.partition(dataList, batchSize); for (List<MyEntity> partition : partitions) { executor.execute(() -> repository.saveAll(partition)); } } // 配置ThreadPoolTaskExecutor @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); // 核心线程数 executor.setMaxPoolSize(20); // 最大线程数 executor.setQueueCapacity(50); // 队列容量 executor.initialize(); return executor; } 3. 其他优化措施 - 数据库索引优化:确保有适当的索引以加快查询速度。 - 事务管理:合理划分事务边界,减少不必要的事务开销。 - 资源回收:及时关闭流和数据库连接,释放资源。 - 硬件扩容:如必要,可增加服务器内存、提升数据库性能。 总结 1. 分页与流式处理:通过分页查询避免一次性加载大量数据至内存,采用流式API逐条处理数据,比如JPA分页查询或JDBC ResultSet流式处理。 2. 响应式编程与流式下载:在处理大数据导出时,使用`StreamingResponseBody`实现服务端流式响应,实时生成和发送数据给客户端,降低内存占用。 3. 批量插入操作:利用JDBC的BatchUpdate功能或JPA的批量保存方法进行大批量数据插入,同时配合线程池技术如`ThreadPoolTaskExecutor`分批处理,分散数据库压力。 4. 系统优化:包括但不限于数据库索引优化、精细化事务管理、资源有效回收以及考虑硬件扩容等手段,以提升整体系统处理大规模数据的能力。 总之,在面对百万级别数据处理时,关键在于采取合理的分页、流式、异步和批量处理策略,并对系统进行全面优化以提高性能和效率。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT技术订阅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档