【问题标题】:Spring batch single threaded reader and multi threaded writerSpring批处理单线程读取器和多线程写入器
【发布时间】:2017-05-29 15:08:40
【问题描述】:

试图找出之前是否有人问过这个问题,但找不到。

这就是问题所在。以下必须通过 Spring 批处理来实现 有一个文件要读取和处理。项目阅读器不是线程安全的。 计划是让多线程同质处理器和多线程同质写入器注入由单线程读取器读取的项目。

有点像下面:

        ----------> Processor #1 ----------> Writer #1
       |
    Reader -------> Processor #2 ----------> Writer #2
       |
        ----------> Processor #3 ----------> Writer #3

尝试了 AsyncItemProcessor 和 AsyncItemWriter,但在处理器上持有调试点导致读取器直到点被释放(即单线程处理)才被执行。

任务执行器尝试如下:

<tasklet task-executor="taskExecutor" throttle-limit="20">

阅读器上的多个线程已启动。

同步阅读器也不起作用。

我试图阅读有关分区器的信息,但它似乎很复杂。

是否有注释将阅读器标记为单线程?将读取数据推送到全局上下文是个好主意吗?

请指导解决方案。

【问题讨论】:

  • 为什么分区太复杂了?
  • 感谢您的评论。我只有几分钟的时间看它,我读得越多,我就越困惑。我已经端到端地完成了它,它似乎不是我问题的传统解决方案,因为我不想拆分我的输入。我错了吗?
  • SynchronizedItemReader 是最佳解决方案吗?
  • 是的,但要确保写作确实是瓶颈。
  • 是的,你是对的。首先需要确定瓶颈。

标签: spring-batch


【解决方案1】:

我想 Spring Batch API 中没有为您正在寻找的模式内置任何内容。需要您自己编写代码来实现您正在寻找的东西。

Method ItemWriter.write 已经根据您的块大小获取了已处理项目的List,因此您可以将List 划分为任意数量的线程。您产生自己的线程并将一段列表传递给要写入的每个线程。

问题在于method ItemProcesor.process(),因为它逐项处理,因此您受到单个项目的限制,并且您无法为单个项目执行太多线程。

因此,挑战在于编写您自己的阅读器,而不是将项目列表而不是单个项目交给处理器,这样您就可以并行处理这些项目,而编写器将处理列表列表。

在所有这些设置中,您必须记住,您生成的线程将超出 Spring 批处理的读取 - 处理 - 写入事务边界,因此您必须自己处理 - 在合并方面处理所有线程的输出并等待所有线程完成并处理任何错误。总而言之,风险很大。

Making a item reader to return a list instead single object - Spring batch

【讨论】:

    【解决方案2】:

    手头有类似的问题。

    这是我目前的做法。正如@mminella 建议的那样,将 itemReader 与 flatfileItemReader 同步为委托。这适用于不错的性能。该代码目前每秒写入约 4K 条记录,但速度并不完全取决于设计,其他属性也有影响。


    尝试了其他方法来提高性能,但都失败了。

    1. 以 FlatFileItemReader 作为委托聚合的自定义同步 ItemReader 但我最终维护了很多导致性能下降的状态。也许需要优化或同步的代码更快。
    2. 在不同的线程中触发每个 insert PreparedStatement 批处理,但并没有提高多少性能,但我仍然指望这个,以防我遇到批处理的单个线程会导致显着性能提升的环境。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      相关资源
      最近更新 更多