我有一个多步骤的Spring Batch作业,在其中一个步骤中,我为读取器中读取的数据创建Lucene索引,以便后续步骤可以搜索Lucene索引。
基于ItemReader
中的读取数据,我将索引传播到几个单独的目录。
如果我指定Step Task Executor为SimpleAsyncTaskExecutor
,只要索引始终写入不同的目录,我就不会遇到任何问题,但有时我会遇到锁定异常。我想,两个线程试图写入相同的索引。
如果我删除SimpleAsyncTaskExecutor
,我就不会遇到任何问题,但写入会变得顺序且缓慢。
如果将索引写入单个目录,是否可以对Lucene Index编写器使用多线程?
我是否需要将索引创建者代码设置为线程安全才能使用SimpleAsyncTaskExecutor
?
索引创建者代码在步骤处理器中。
答案 0 :(得分:1)
我正在使用Lucene 6.0.0和IndexWriter API Doc,
注意:IndexWriter实例完全是线程安全的,这意味着 多个线程可以同时调用它的任何方法。如果你的 应用程序需要外部同步,你不应该 在IndexWriter实例上同步,因为这可能会导致死锁; 使用你自己的(非Lucene)对象。
我正在创建多个编写器实例,这会导致问题。单个编写器实例可以传递给任意数量的线程,只要该编写器的其余代码是线程安全的。
我使用了单个编写器实例和并行化块。每个并行块都写入同一目录,没有任何问题。
为了并行化块,我必须使我的块组件 - 读取器,处理器和编写器是线程安全的。