Lucene.net优化未完成的循环



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

这引发了以下问题:
1.什么能使OptimizeMergesPending()保持返回为真
2.什么会导致索引和优化过程的失效
3.你知道Lucene.net的新版本是否面临同样的行为吗?

感谢

IndexWriter.OptimizeMergesPending的xmldocs声明,"如果挂起的merges或正在运行的Mergess中的任何合并都是优化合并",它将返回true。IndexWriter.DoWait的内联文档指出,它只会等待一秒钟,以避免某些通知可能无法触发的问题,由调用方重新评估等待条件。我已经链接到2.9.4g源代码,所以新版本也包含这种行为。

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

反问题;

  1. 你为什么打IndexWriter.Optimize?Lucene可以处理多个段,事实上,当只有几个段发生更改时,重新打开索引比重新打开包含整个索引的全新段更容易。如果您对段的当前处理有问题,您可以编写自己的MergePolicy。从3.5版本开始,它就被弃用了,Lucene.Net目前落后于3.5版本(目前它已经达到3.0.3版本,4.x的移植正在进行中)
  2. 你锁定过IndexWriter吗?我链接的代码显示代码执行了lock (this) {...},这很糟糕,如果您也锁定了编写器,可能会导致死锁问题。这可能看起来就像你的代码挂起了,你可能已经构建的任何干净的线程终止都不会被触发(因为线程只是阻塞)

关于持续变化的索引的更新

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

最新更新