2011-05-05 89 views
10

Lucene鼓励重复使用来自多个线程的IndexWriter。Lucene IndexWriter线程安全

鉴于两个线程可能对IndexWriter有引用,如果线程A在写入器上调用close,那么线程B将留下一个无用的写入器。但就我的理解,lucene以某种方式知道另一个线程使用相同的作者并推迟其关闭。

这的确是这样吗? lucene如何跟踪另一个线程使用该作者?

编辑 从答案来看,关闭IndexWriter是不正确的。但是这带来了一个新问题:如果一个人保持打开IndexWriter,基本上阻止从另一个JVM访问此索引(例如,在集群或许多应用程序之间的共享索引中)。

回答

6

如果一个线程关闭了IndexWriter而其他线程仍在使用它,您将得到不可预知的结果。我们尝试让其他线程碰到AlreadyClosedException,但这只是尽力而为(不保证)。 EG,你也可以很容易地遇到NullPointerException。所以你必须同步外部,以确保你不这样做。最近(现在只有在Lucene的trunk中,最终为4.0),IndexWriter内部的一个大的线程瓶颈被修正了,允许段冲刷同时运行(以前它们是单线程的)。在并发硬件上运行多个索引线程的应用程序中,这可以大大提高索引吞吐量。详情请参阅http://blog.mikemccandless.com/2011/05/265-indexing-speedup-with-lucenes.html

0

您是指IndexWriter.close()方法中的waitForMerges标志?

关闭索引,无论是否等待当前正在运行的合并完成。这仅在使用在后台线程中运行合并的MergeScheduler时才有意义。

Lucene通常使用后台线程来合并跨多个线程发生的分段写入 - 写入本身立即发生,但整合发生异步。

当关闭作家,你应该允许它完成整合过程,否则:

是很危险的总是调用close(假的),尤其是当IndexWriter类未打开,很长,因为这可能导致“合并饥饿”,从而长期合并永远不会有机会完成。随着时间的推移,这会导致索引中的部分太多。

所以作者并不“知道”你的话题,就你的意思而言。

+0

因此,如果两个线程正在使用同一个编写器并且一个线程关闭它,那么另一个线程确实留下了一个无用的编写器? – yannisf 2011-05-05 15:00:20

+1

@yannisf:好的,我想是的,但对于任何可变的共享对象来说,这是一样的 - 一个线程可以使共享对象无用。这似乎并不是特例。 – skaffman 2011-05-05 15:01:25

1

IndexWriter的线程安全和重用意味着您可以有多个线程使用该实例来创建/更新/删除文档。如果你在一个线程中关闭了编辑器,它确实会让其他人感到困惑。