【发布时间】:2021-03-01 14:09:53
【问题描述】:
我正在为我们的文件上传过程实施春季批处理作业。我的要求是读取一个平面文件,应用业务逻辑,然后将其存储在数据库中,然后发布一条 Kafka 消息。
我有一个基于块的步骤,它使用自定义读取器、处理器、写入器。该过程运行良好,但处理大文件需要大量时间。
处理一个包含 60K 记录的文件需要 15 分钟。我需要将它减少到不到 5 分钟,因为我们将消耗比这更大的文件。
根据https://docs.spring.io/spring-batch/docs/current/reference/html/scalability.html,我理解将其设为多线程会提高性能,但会以重启能力为代价。但是,我使用的是 FlatFileItemReader、ItemProcessor、ItemWriter,它们都不是线程安全的。
关于如何提高性能的任何建议?
这是编写器代码:-
public void write(List<? extends Message> items) {
items.forEach(this::process);
}
private void process(Message message) {
if (message == null)
return;
try {
//message is a DTO that have info about success or failure.
if (success) {
//post kafka message using spring cloud stream
//insert record in DB using spring jpaRepository
} else {
//insert record in DB using spring jpaRepository
}
} catch (Exception e) {
//throw exception
}
}
最好的问候, 普雷蒂
【问题讨论】:
-
在进行多线程或分区之前,您是否对当前工作进行了概要分析?块大小的值是多少?低值意味着很多事务,这可能是一个性能问题。你工作的瓶颈是什么?您是处理逻辑还是 IO(读/写操作)?这些问题对于了解您是否真的需要扩展您的工作以及如果需要,实施哪种扩展策略非常重要。
-
感谢@MahmoudBenHassine 回来。我已将块大小定义为 500。我确实尝试记录读取器、写入器、处理器周围的时间指标。作家是花费最多时间的人。下面是 spring batch 生成的千分尺统计:-Writer (spring.batch.chunk.write) statistic: "TOTAL_TIME", value: 766.972706343 Process (spring.batch.item.process) statistic: "TOTAL_TIME", value: 3.238209216 读(spring.batch.item.read) 统计:“TOTAL_TIME”,值:4.164657738
-
感谢您的更新。你能分享你的作家配置吗?另外,您使用哪个作业存储库?默认的基于地图的作业存储库可能会减慢速度。
-
谢谢。我正在使用默认的 MapJobRegistry。 Writer 实现 ItemWriter> 。用作者的逻辑更新了我原来的帖子。
-
基于地图的作业存储库可能很慢并且已弃用:github.com/spring-projects/spring-batch/issues/3780,I 建议使用基于 JDBC 的作业存储库。此外,您的作者似乎没有使用批量更新:您正在为循环中的每个项目发出保存操作。您应该执行
saveAll(items)之类的操作,以便在一次批量操作中一次保存所有项目。我们在 4.3 中引入了类似的改进:docs.spring.io/spring-batch/docs/4.3.x/reference/html/…,您可以从中获得灵感。
标签: spring-boot performance spring-batch