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

Multithreading 单文件到多文件的Spring批处理多线程处理,multithreading,spring,spring-batch,Multithreading,Spring,Spring Batch,我的问题陈述。读取包含1000万数据的csv文件并将其存储在db中。尽可能缩短时间。 我使用java的简单多线程执行器实现了它,其逻辑几乎类似于SpringBatch的块。从csv文件中读取预配置数量的数据,然后创建一个线程,并将数据传递给线程,该线程验证数据,然后写入在多线程中运行的文件。完成所有任务后,我将调用sql loader来加载每个文件。现在我想将此代码移动到spring batch(我是spring batch的新手) 以下是我的问题 1.在任务中,是否可以使ItemReader到

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

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

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

  • 关于多线程阅读答案;它会为你指明正确的方向。另外,在示例中,还有一些关于重新启动CSV文件的考虑
  • 如果线程出现错误,作业应该自动失败:我从未尝试过,但这应该是默认行为
  • 这可能是一个开始。另外,关于退避策略——在短暂故障后重试时,等待一段时间通常会有所帮助 再次尝试之前,请执行位,因为失败通常是由 一些只有等待才能解决的问题。如果 RetryCallback失败,RetryTemplate可以根据需要暂停执行 以确保退避政策到位
  • 让我知道这是否有帮助,或者你如何解决问题,因为我对我(未来)的工作感兴趣

    我希望我的指示能有所帮助。

    以下是我解决问题的方法

  • 读取一个文件并使用缓冲和文件通道读写器(最快的文件读写方式,甚至spring批处理也使用相同的方式)对文件进行分块(拆分文件)。我实现了这样一种方法,即在作业启动之前执行该方法(但是可以使用方法调用器将作业作为步骤执行)

  • 以目录位置作为作业参数启动作业

  • 使用multiResourcePartitioner,它将获取目录位置,并在单独的线程中为每个文件创建一个从属步骤
  • 在从属步骤中,获取从分区器传递的文件,并使用spring batchs itemreader读取该文件
  • 使用数据库项编写器(我使用的是mybatis batch itemwriter)将数据推送到数据库
  • 最好使用等于步骤提交计数的拆分计数

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

    <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>
    
    
    
    满满的


    希望能有所帮助。

    感谢@bellabax的建议,我已经完成了使用分段的示例项目并行工作,但我仍然不喜欢使用分段,因为分段涉及DB操作,而我真的不喜欢,因为分段将创建一个超头任务(在我的情况下)将数据写入数据库,然后从数据库读取数据,写入文件,最后调用sql loader,我的另一个限制是我在列中使用ADT数据,因此sql loader为我提供了更好的方法。嗨,我有一个问题,我想处理XML中的数百万用户,并将其转储到数据库中,并希望使用覆盖线程/分区,你能给出你的实现的示例吗?这样我就可以引用它了,因为RII在分割文件时有两个问题。首先,较大的文件包含页眉和页脚记录,不确定文件何时被拆分,如何找到页眉和页脚记录以对其执行某些业务验证。第二个问题,如何确保文件不会被拆分,不会打断中间的行?