【问题标题】:Lucene .Net, do i need to close IndexWriterLucene .Net,我需要关闭 IndexWriter
【发布时间】:2015-06-24 10:02:38
【问题描述】:

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

我们在IndexWriter上调用如下函数

AddDocument();
DeleteDocuments();
DeleteAll();
Optimize();
Commit();

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

谢谢戴夫

【问题讨论】:

    标签: c# lucene lucene.net


    【解决方案1】:

    文档说可以,但前提是您要关闭应用程序本身 - 否则,不行。这是 Lucene.Net 4.8 中 IndexWriter.Dispose 的文档:

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

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

    请注意,这可能是一项昂贵的操作,因此,请尝试重复使用单个 writer 而不是关闭和打开一个新的。见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 个线程尝试写入,一个挂起或失败,具体取决于您的代码编写方式。如果确实出现这种情况,您可能希望实现一个写入队列,以便线程可以快速将他们想要写入的内容交付到像 ConcurrentQueue 这样的廉价数据结构中,然后让那些写入操作启动写入操作(如果没有运行),并且继续出队,直到所有内容都写完 - 然后重新入睡。

    【讨论】:

      【解决方案2】:

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

      我还建议在using-block 中使用每个IDisposeable-object,它只调用Dispose()

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

      对于 Lucene IndexWriter 我不太确定,但是当它使用文件作为其索引时(这是我假设的),那么您就有理由应该调用 Dispose

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

      【讨论】:

      • 谢谢,我了解 IDisposable 和 Dispose 模式,我正在寻找特定于 Lucene 的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多