为分区从属步骤并行执行块

时间:2016-10-07 07:27:07

标签: java spring-batch

我的这个问题是对我另一个SO Question的扩展。由于这看起来不可能,我试图并行执行块并行/分区从属步骤。

Article表示只需将SimpleAsyncTaskExecutor指定为步骤的任务执行程序即可开始并行执行块。

@Bean
public Step masterLuceneIndexerStep() throws Exception{
        return stepBuilderFactory.get("masterLuceneIndexerStep")
                .partitioner(slaveLuceneIndexerStep())
                .partitioner("slaveLuceneIndexerStep", partitioner())
                .gridSize(Constants.PARTITIONER_GRID_SIZE)
                .taskExecutor(simpleAsyntaskExecutor)
                .build();
    }

    @Bean
    public Step slaveLuceneIndexerStep()throws Exception{
        return stepBuilderFactory.get("slaveLuceneIndexerStep")
                .<IndexerInputVO,IndexerOutputVO> chunk(Constants.INDEXER_STEP_CHUNK_SIZE)
                .reader(luceneIndexReader(null))
                .processor(luceneIndexProcessor())
                .writer(luceneIndexWriter(null))
                .listener(luceneIndexerStepListener)
                .listener(lichunkListener)
                .throttleLimit(Constants.THROTTLE_LIMIT)
                .build();
    }

如果我为slave步骤指定.taskExecutor(simpleAsyntaskExecutor)则作业失败。主步骤中的行.taskExecutor(simpleAsyntaskExecutor)正常工作,但块并行处理串行和分区步骤。

是否可以并行化slaveLuceneIndexerStep()

的块

基本上,每个块都以顺序方式将Lucene索引写入单个目录,并且我希望进一步并行化每个目录中的索引编写过程,因为Lucene IndexWriter是线程安全的。

1 个答案:

答案 0 :(得分:0)

我可以通过以下方式从分区的从属步骤中启动并行块

1.我首先照顾我的读者,处理器和编写器是线程安全的,以便这些组件可以参与并行块而不会出现并发问题。

2.我将任务执行程序保留为主步骤为concurrencyLimit,因为从属步骤长时间运行,我希望在某个时间点准确启动N线程。我通过设置任务执行器的ThreadPoolTaskExecutor来控制N.

3.然后我将client_id设置为slave步骤的任务执行程序。此池被所有从属步骤用作公共池,因此我将其核心池大小设置为最小值N,以便每个从属步骤至少获得一个线程,并且不会发生饥饿。您可以根据系统容量增加此线程池大小,并且我使用了线程池,因为块是较小的运行进程。

使用线程池还处理我的应用程序的特定情况我的分区是WAITING所以当较小的客户端完成时,相同的线程会被更大的客户端自动重用,并且client_id分区创建的不对称性会被处理,因为数据到为每个客户处理的变化很大。

主步骤任务执行程序只是启动所有从属步骤线程并进入{{1}}状态,而从属步骤块由从属步骤中指定的线程池处理。