【问题标题】:Design ideas for Spring Batch Job better performnaceSpring Batch Job 更好性能的设计思路
【发布时间】:2017-01-07 22:00:33
【问题描述】:

我写了一个 spring 批处理作业并使用SimpleAsyncTaskExecutor。我尝试使用ThreadPoolExecutor,但这比SimpleAsyncTaskExecutor 的性能要慢得多。

这些是工作的要点,

1.处理部分工作是最耗时的部分。它基本上将大量SQL SELECTs 触发到与读取器和写入器不同的数据库表中。 Reader 和 Writer 不需要太多时间。Processor 非常复杂。

2. 处理器返回记录后立即将处理器的输出写入数据库的功能要求。这是必要的,因为 处理器为作家找到东西的情况很少见,我们需要 结果立即持续。简而言之,它是一项业务 要求有chunk size =1

我担心工作的表现。如果我让处理器逻辑有点轻量级,性能会增加很多,所以我猜处理器是瓶颈。

我只是使用SimpleAsyncTaskExecutor 来实现并行性。作业应该在功能强大的多处理器系统上运行。

关于我可以在 Spring Batch 方面做些什么以加快这项工作的任何想法?

工作只有这一步。

@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();
    }

【问题讨论】:

    标签: spring-batch


    【解决方案1】:

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

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

    当我必须读取额外数据来处理我的项目时,我使用两种模式:

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

    【讨论】:

    • 其实工作就是在处理器中从超过8000万行的表中寻找匹配的记录。由于我无法将整个表存储在内存中(由于表大小非常大),我使用的选项是使用适当的 WHERE 子句触发 SELECT。对于来自阅读器的单个输入值,平均会触发 200 多个 SELECT(即要执行 200 多个规则)。 WHERE 子句以这样一种方式进行了优化,它应该花费最佳时间。
    • 那些 200 多个选择对于每个已读项目是否总是相同的选择?如果是,那么我建议使用我的第二种模式。每个读取项执行 200 多次额外的数据库调用永远不会带来令人满意的性能。我的意思是,如果您只有 1000 个项目,那么您会产生超过 200'000 个调用。我的方法会将这减少到几百个电话。
    • 不,这些规则不是固定的,而是为处理器的每个输入动态生成的。
    • 如果性能成为问题,您将不得不找到一种方法来减少数据库调用的数量。从您所写的内容来看,我预计您的批处理花费了大约 99% 的时间与数据库通信。有没有办法以一种至少一个块中的所有项目都使用相同查询的方式来组织你的阅读项目?
    • 是的,你在 db 部分是正确的。到目前为止,规则对处理器的每个输入都非常具体,但我会看看我是否可以分组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 2023-02-24
    • 2019-10-17
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    相关资源
    最近更新 更多