Lucene .Net,我需要关闭 IndexWriter 吗

Lucene .Net, do i need to close IndexWriter

我们遇到 Lucene .Net 抛出 LockObtainFailedException 的锁定问题。这是一个多租户站点,每个客户在磁盘上都有自己的物理搜索索引,并使用 static 列表 IndexWriters,每个索引一个来控制更改。

我们在 IndexWriter

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

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

谢谢戴夫

当您不再需要该对象时使用 Close/Dispose 总是一个好主意。开发人员公开这些方法是有原因的。通常,文档会在何时使用这些方法时提供额外提示。

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

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

在 Lucene IndexWriter 的情况下我不是很确定,但是当它使用文件作为索引时(这是我假设的),那么你就有理由调用 Dispose .

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

文档说是的,但只有当您终止应用程序本身时才会如此 - 否则,不会。这是 Lucene.Net 4.8 中 IndexWriter.Dispose 的文档:

Commits all changes to an index, waits for pending merges to complete, and closes all associated files.

This is a "slow graceful shutdown" which may take a long time ...

Note that this may be a costly operation, so, try to re-use a single writer instead of closing and opening a new one. See Commit() for caveats about write caching done by some IO devices.

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

因此,您应该调用 .Dispose(),但通常只在您关闭应用程序时调用一次。

您已经在致电 .Commit(),他们建议您改用此电话。我猜你的问题实际上与线程有关。我只是在学习 Lucene,但如果我处于你的位置,我会尝试在对 Lucene 的任何写入调用周围放置一个标准的 .Net 锁,以便一次只有一个线程可以访问写入。如果它解决了您的问题,您就知道它正在线程化。

锁非常痛苦,而且 Lucene 写入可能需要很长时间,所以如果锁解决了这个问题,它可能会引入其他问题,例如 2 个线程尝试写入和一个挂起或失败,具体取决于您的代码编写方式。如果确实出现这种情况,您可能想要实现一个写队列,以便线程可以快速将他们想要写入的内容移交给像 ConcurrentQueue 这样的廉价数据结构,然后让那些写操作启动写操作,如果 none是 运行,并继续出列直到所有内容都写完 - 然后返回睡眠。