Lucene.net优化未完成的循环

时间:2013-12-01 09:48:58

标签: .net lucene.net

我正在使用Lucene.net版本2.9.1,并在调用Optimize时遇到以下问题: 我注意到一些优化调用可能需要几个小时,而当这需要很长时间时,索引和优化的过程不会被杀死。 当我使用源代码时,我设法跟踪问题:导致此行为的调用是Optimize(int maxNumSegments, bool doWait) - 并且在此方法中,对OptimizeMergesPending()的重复调用始终返回true,并且循环继续工作并调用此方法,直到此调用将返回,否则可能需要很长时间。

这提出了以下问题:
1.什么可以导致OptimizeMergesPending()保持回归真实?
2.什么可能导致杀死索引和优化过程的失败? 3.你知道Lucene.net的新版本是否会出现同样的行为吗?

由于

1 个答案:

答案 0 :(得分:3)

xmldocs for IndexWriter.OptimizeMergesPending表示如果pendingMerges或runningMerges中的任何合并都是优化合并,它将返回true。 inline documentation for IndexWriter.DoWait表示它只会等待一秒钟,以避免可能无法触发某些通知的问题,由呼叫者重新评估等待条件。我已链接到2.9.4g源代码,因此较新的版本也包含此行为。

一个不可杀死的进程是一个操作系统问题,只要它没有在内核/系统调用中被阻止,你就应该始终能够终止进程。我们需要查看进程转储来调试这些问题。 (或者更好地解释你是如何试图杀死这个过程的......)

反的问题;

  1. 你为什么打电话给IndexWriter.Optimize? Lucene可以处理多个段,事实上,当只有少数段发生变化时重新打开索引比重新打开包含整个索引的全新段更容易。如果您对当前段的处理有问题,您可以编写自己的MergePolicyIt has been deprecated as of 3.5,Lucene.Net目前落后(目前高达3.0.3,正在进行4.x的移植)。
  2. 您是否曾锁定过IndexWriter?我链接的代码显示代码执行lock (this) {...}这很糟糕,如果您锁定了编写器,可能会导致死锁问题。这可能看起来好像你的代码挂起了,你可能已经构建的任何干净的线程终止都不会被触发(因为线程只是阻塞)。
  3. 关于不断变化的指数的更新。

    1. 从不致电IndexWriter.Optimize(),在实际合并期间以及重新打开读卡器时,都会导致不必要的cpu​​和io加载。
    2. 在单独的线程上或在调用IndexWriter.Commit时重新打开您的读者和搜索者。不要等到用户需要搜索才能重新打开它。
    3. 调用IndexReader.Reopen()而不是IndexReader.Open()。第一个只加载已更改的段并重用已读取且未更改的段。 (请记住,删除只是一个单独的位图,它只会重新读取位图而不是完整的段。)
    4. 考虑升级到Lucene.Net 3.0.3并使用IndexWriter.IndexReaderWarmer编写自定义预热逻辑,以确保在用户开始使用之前将您的段完全读入缓存/内存。