Spring Batch并发加分区读取数据库的完美优化方案

本文介绍了如何使用Spring Batch优化批处理,解决读取大型数据库的效率问题。初始方案通过单线程发送HTTP请求处理26万条记录耗时24小时。优化一采用分页读取数据库,减少请求次数,将运行时间缩短至1小时。优化二通过并发10个Step,每个Step读取数据库的不同部分,进一步将时间降至10分钟。
摘要由CSDN通过智能技术生成

今天我们会介绍Spring Batch批处理读写大型数据库的优化方案

背景介绍

现在我们有两个数据库,数据库A是新数据库,里面保存了公司所有员工的员工工号,数据库B是老数据库,里面保存了公司所有员工对应的详细信息,数据库B里面的数据会每天被定时任务更新。

我们希望用两个定时任务来维护我们的两个数据库,第一个定时任务会把数据库A中所有的员工工号发送给人力资源部门系统,再把从人力资源部门返回的信息写到公司的云盘中。

第二个定时任务会读取云盘中被写入的文件,解析并写出到数据库B中,从而达到每日更新的目的。

初步方案

以上就是我们的需求啦,现在程序员小明推出以下解决方案:

  1. 人力资源系统新开一个接口,接收一条存储了员工工号的http请求,并返回该员工的详细信息。
  2. 我们开一个新的定时任务,每天在固定时间会被执行,定时任务的Reader会将数据库内的一条条员工工号读取出来并传给Processor,这里我们设置的chunk size为100,在Processor中我们会把每一个员工工号发送给人力资源再接受返回数据,最后再按批次写出到云盘。
  3. 第二个定时任务开始工作,读取云盘文件并更新数据库B,本篇文章先略过这个部分。

结果使用该方案定时任务跑了整整24小时才跑完。。

问题分析:

  • 现公司员工记录为26万,按照现在的方案我们一共需要发送并处理26万条http请求。
  • 所有请求单线程序列化运行,不具备任何并发能力。

优化方案一.

优化People接口,并优化每一次Reader和Processor的读和处理过程。

这里Reader的每一次读取都需要对数据库进行分页,主要需要pageNum 和 pageSize这两个变量,变量offset就是pageNum 乘以 pageSize,每读一次pageNum加一。

我们可以将变量注入XML的MySQL语句中,通过MyBatis对数据库进行分页读,每次读100个数据,将读取到的数据打包成一个list一次性传递给Processor。Processor再将List传给人力资源系统,之后利用StringBuilder将返回的数据封装成一个String,传递给Writer直接写出。

这样一来http请求数量为之前的1/100,定时任务运行时间从24小时被缩短到了1小时。

这里主要为大家分享以下代码,自定义Reader类,Processor类和Writer类的实现:

public class BatchReader<T> implements ItemReader<List<T
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值