Spring批处理单文件到多文件的多线程处理

时间:2013-09-07 11:21:38

标签: multithreading spring spring-batch

我的问题陈述。读取包含1000万个数据的csv文件并将其存储在db中。尽可能短的时间。

我使用java的简单多线程执行程序实现了它,逻辑几乎类似于spring batch的块。从csv文件中读取预配置数量的数据,然后创建一个线程,并将数据传递给验证数据的线程,然后写入在多线程中运行的文件。完成所有任务后,我正在调用sql loader来加载每个文件。现在我想把这个代码移到spring批处理(我是新手到春季批次)

这是我的问题 1.在任务中,是否可以将ItemReader设置为Item writer多线程(因为我在线程写入数据之前读取文件创建一个新线程来处理数据)?如果不是我需要创建两个步骤第一步读取单线程文件和另一个步骤,即多线程写入单个文件,但如何将数据列表传递给上一个任务中的另一个任务。
2.如果单个线程中出现任何故障,如何停止整批作业处理 3.如果在一定间隔后出现故障,如何重试批处理作业。我知道在发生故障时存在重试选项,但在发生故障的情况下,我找不到在某个间隔后重试任务的选项。这里我不是在谈论调度程序,因为我的批处理作业已经在调度程序下运行,但是在失败时它必须在3分钟后重新运行。

3 个答案:

答案 0 :(得分:2)

以下是我解决问题的方法。

  1. 使用缓冲和文件通道读写器(文件读/写的最快方式,即使是春季批次使用相同的文件)读取文件并对文件进行分块(拆分文件)。我实现了这是在作业开始之前执行的(但是可以使用作为步骤使用方法调用程序执行它)

  2. 使用目录位置作为作业参数启动作业。

  3. 使用multiResourcePartitioner获取目录位置,并为每个文件在单独的线程中创建从属步骤
  4. 在Slave步骤中获取从Partitioner传递的文件并使用spring batchs itemreader读取文件
  5. 使用数据库项目编写器(我正在使用mybatis批量项目编写器)将数据推送到数据库。
  6. 最好使用等于commit-count of step的分割计数。

答案 1 :(得分:1)

  1. 关于多线程阅读How to set up multi-threading in Spring Batch?答案;它会指向正确的方向。此外,在this示例中,还有一些关于CSV文件重启的考虑因素
  2. 如果线程上出现一些错误,作业应该会自动失败:我从未尝试过,但这应该是默认行为
  3. Spring Batch How to set time interval between each call in a Chunk tasklet可以是一个开始。此外,official doc关于退避政策 - 在暂时失败后重试时,通常会有助于等待 再次尝试之前,因为通常失败是由 一些只能通过等待解决的问题。如果一个 RetryCallback失败,RetryTemplate可以暂停执行 到了BackoffPolicy。
  4. 让我知道这个帮助或你如何解决问题,因为我对我(未来)的工作感兴趣!
    我希望我的指示可以有所帮助。

答案 2 :(得分:-1)

您可以将输入文件拆分为多个文件,使用Partitionner并使用线程加载小文件,但出错时,必须在清除DB后重新启动所有作业。

<batch:job id="transformJob">
    <batch:step id="deleteDir" next="cleanDB">
        <batch:tasklet ref="fileDeletingTasklet" />
    </batch:step>
    <batch:step id="cleanDB" next="split">
        <batch:tasklet ref="countThreadTasklet" />
    </batch:step>
    <batch:step id="split" next="partitionerMasterImporter">
        <batch:tasklet>
            <batch:chunk reader="largeCSVReader" writer="smallCSVWriter" commit-interval="#{jobExecutionContext['chunk.count']}" />
        </batch:tasklet>
    </batch:step>
    <batch:step id="partitionerMasterImporter" next="partitionerMasterExporter">
        <partition step="importChunked" partitioner="filePartitioner">
            <handler grid-size="10" task-executor="taskExecutor" />
        </partition>
    </batch:step>
</batch:job>

完整example code (on Github)

希望得到这个帮助。