【问题标题】:Lucene Index broken after LockObtainFailedExceptionLockObtainFailedException 后 Lucene 索引损坏
【发布时间】:2017-09-08 07:12:53
【问题描述】:

我在 asp-core 项目中使用 Lucene。但是每隔 2-4 天我的索引就会损坏。所以我记录了异常并得到了以下堆栈跟踪:

2017-09-06 10:13:50.8338|发生未处理的异常:锁定 获取超时: SimpleFSLock@e:\inetpub\Static_Data\GKHUB\lucene_index\write.lock: System.IO.IOException:锁定文件 'e:\inetpub\Static_Data\GKHUB\lucene_index\write.lock' 已经 exists.EXCEPTION OCCURRED:Lucene.Net.Store.LockObtainFailedException

经过一番研究,我发现,

无法获取 write.lock 时会引发此异常。当作者试图打开另一个作者已经打开的索引时,就会发生这种情况。[src]

所以第二个更新请求无法更新索引。但是为什么后来整个索引都坏了呢? 我的代码没有做任何特别的事情:

public void UpdateIndex(Document doc, int idToUpadate)
{
    var indexwriterConfig = new IndexWriterConfig(LuceneVersion.LUCENE_48, Analyzer);
    indexwriterConfig.WriteLockTimeout = 5000; // doesn't fix the problem
    using (var writer = new IndexWriter(GetLuceneDirectory, indexwriterConfig)) {
        try {
            writer.UpdateDocument(new Term("Id", idToUpadate.ToString()), doc);
            writer.Commit();
        }
        catch (Exception e) {
            Debug.WriteLine(e);
            writer.Rollback();
        }
    }
}

【问题讨论】:

  • 你有多少更新?您实际上在每个更新方法上创建了 indexwriter 的新实例,这不是一个好主意
  • 通常一次一个,如果有几个,就会出现这个错误。为什么这是个坏主意?

标签: asp.net asp.net-core lucene


【解决方案1】:

正如您在问题中已经提到的:

LockObtainFailedException 在 write.lock 不能被抛出时被抛出 获得。当作者试图打开一个索引时,就会发生这种情况 另一个作家已经打开了。

如果您有多个更新,就会发生这种情况,在您的代码中,您正在创建多个尝试获取索引锁定的 IndexWriter 实例。您应该尝试重新使用单个编写器,而不是关闭并打开/创建一个新编写器。这应该可以解决您的问题。

还有,别忘了,那

IndexWriter 实例是完全线程安全的,这意味着多个 线程可以同时调用它的任何方法

【讨论】:

  • 但我有 2 个索引...一个用于 mediaContents,一个用于我的产品。 (在不同的目录中)所以我至少需要 2 个 indexWriter。对?我每次都必须将目录传递给作者。
  • 是的,在这种情况下 2 个索引编写器应该没问题,只是不要在每次更新时创建一个
猜你喜欢
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多