Spring Batch Job的设计思路更好地执行

时间:2016-08-31 10:43:44

标签: spring-batch

我已经编写了一个弹簧批处理作业并使用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();
    }

1 个答案:

答案 0 :(得分:1)

如果你需要一个1的chunksize,那么就没有办法快速。您产生了很多开销(例如,更新每个项目的批处理表)。此外,从处理器中调用DB调用也会对性能产生非常不利的影响,因为您会为每个项目再次生成sql调用。

良好性能的关键 - 在使用DB时 - 是减少发送到数据库的调用次数。例如。通过使用batchUpdates或SQL语句为整个块选择数据,而不是为单个项目(使用适当的IN子句)。

当我必须阅读其他数据来处理我的项目时,我使用两种模式:

  • 首先,我尝试使用合并阅读器选择附加数据(合并阅读器通过将数据按照相同的键排序,将来自不同阅读器的数据合并在一起)
  • 第二,如果那是不可能的,我使用一个特殊的编写器,它也执行处理部分。这样,您可以使用适当的IN子句实现Select,该子句选择完整块的数据。因此,在oracle的情况下,您只需要一次调用即可获取一千个项目的数据。