Lucene .Net,我需要关闭IndexWriter吗?

时间:2015-06-24 10:02:38

标签: c# lucene lucene.net

我们遇到Lucene .Net投掷LockObtainFailedException的锁定问题。它是一个多租户站点,每个客户在光盘上获得自己的物理搜索索引,并使用static IndexWriters列表,每个索引一个用于控制更改。

我们在IndexWriter

上调用以下函数
AddDocument();
DeleteDocuments();
DeleteAll();
Optimize();
Commit();

我注意到我们从未在Close()上致电Dispose()IndexWriter,并想知道这是否是良好做法,可能是问题的原因。

谢谢戴夫

2 个答案:

答案 0 :(得分:2)

文档说是,但仅当您终止应用程序本身时-否则,否。这是IndexWriter.Dispose在Lucene.Net 4.8中的文档:

  

对索引提交所有更改,等待挂起的合并完成,   并关闭所有关联的文件。

     

这是“缓慢的正常关机”,可能需要很长时间...

     

请注意,这可能是一项昂贵的操作,因此,请尝试重复使用一个   作家,而不是关闭和打开一个新的。参见Commit()   有关由某些IO设备完成写缓存的警告。

https://github.com/apache/lucenenet/blob/master/src/Lucene.Net/Index/IndexWriter.cs#L996

因此,您应该调用.Dispose(),但是通常在关闭应用程序时仅调用一次。 It is not however clear whether you need to Dispose() its underlying objects.

您已经在致电.Commit(),他们建议这样做。我猜你的问题实际上与线程有关。我只是在学习Lucene,但是如果我处于您的位置,我将尝试在对Lucene的所有写调用周围放置一个标准.Net锁,以便一次仅一个线程可以访问写操作。如果它解决了您的问题,则说明它正在线程化。

锁非常痛苦,Lucene的写入可能会花费很长时间,因此,如果锁解决了此问题,则可能会引入其他问题,例如2个尝试写入的线程以及1个挂起或失败的线程,具体取决于您的代码编写方式。如果确实发生了这种情况,则您可能希望实现一个Write Queue,以便线程可以快速将要写入的内容传递给诸如ConcurrentQueue之类的廉价数据结构,然后让那些写操作启动写操作(如果没有运行),并且保持出队,直到一切写完为止-然后回到睡眠状态。

答案 1 :(得分:0)

当你不再需要这个物体时使用关闭/处理总是一个好主意。开发人员公开这些方法的原因是有原因的。通常,文档提供了何时使用这些方法的其他提示。

我还建议在IDisposeable - 块中使用每个using - 对象,只调用Dispose()

这使对象能够清理和释放资源。在框架对象的情况下,这并不重要,因为垃圾收集器迟早会关心,但是在系统对象或文件系统句柄Dispose等句柄的情况下变得很重要。这些手柄可能会保持打开状态。

在Lucene IndexWriter的情况下,我并不完全确定,但是当它使用文件作为索引时(这是我假设的),那么你就有理由调用Dispose。< / p>

当句柄/连接/等保持打开状态时,可能会导致此类异常。所以,是的,你应该使用Close() / Dispose()