我已经编写了一个弹簧批处理作业并使用SimpleAsyncTaskExecutor
。我尝试使用ThreadPoolExecutor
,但这比SimpleAsyncTaskExecutor
的性能要慢得多。
这些是关于工作的要点,
1.处理部分工作是最耗时的部分。它基本上会激活大量的SQL SELECTs
到不同的数据库表而不是读者和作者。
读者和作者并不需要太多时间。处理器非常复杂。
2.处理器返回记录后,有一个功能要求将处理器的输出写入DB。这是必要的,因为
处理器为作家找东西很少见,我们需要
结果立即持续存在。简而言之,它是一项业务
要求chunk size =1
我担心这份工作的表现。如果我使处理器逻辑有点轻量级,性能会增加,所以我猜处理器是瓶颈。
我只是使用SimpleAsyncTaskExecutor
来实现并行性。 Job应该在强大的多处理器系统上运行。
关于我可以在Spring Batch方面做些什么来更快地完成这项工作的任何想法?
Job只有这一步。
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemReader<RemittanceVO> syncReader, ItemWriter<RemittanceClaimVO> writer,
ItemProcessor<RemittanceVO, RemittanceClaimVO> processor) {
return stepBuilderFactory.get("step1")
.listener(zeroReadRowsStepExecutionListener)
.<RemittanceVO, RemittanceClaimVO> chunk(Constants.SPRING_BATCH_CHUNK_SIZE)
.reader(syncReader)
.listener(afterReadListener)
.processor(processor)
.writer(writer)
.taskExecutor(simpleAsyntaskExecutor)
.throttleLimit(Constants.THROTTLE_LIMIT)
.build();
}
答案 0 :(得分:1)
如果你需要一个1的chunksize,那么就没有办法快速。您产生了很多开销(例如,更新每个项目的批处理表)。此外,从处理器中调用DB调用也会对性能产生非常不利的影响,因为您会为每个项目再次生成sql调用。
良好性能的关键 - 在使用DB时 - 是减少发送到数据库的调用次数。例如。通过使用batchUpdates或SQL语句为整个块选择数据,而不是为单个项目(使用适当的IN子句)。
当我必须阅读其他数据来处理我的项目时,我使用两种模式: