Indexing Lucene.Net 2.9.2:添加多个文档时出现OOM异常
我正在尝试使用Lucene.NET 2.9.2为大约10.000.000个文档编制索引。这些文档(不同长度的论坛帖子)从MSSQL数据库中以10.000的大容量获取,然后传递到我的Lucene.NET包装类LuceneCorpus:Indexing Lucene.Net 2.9.2:添加多个文档时出现OOM异常,indexing,lucene.net,out-of-memory,Indexing,Lucene.net,Out Of Memory,我正在尝试使用Lucene.NET 2.9.2为大约10.000.000个文档编制索引。这些文档(不同长度的论坛帖子)从MSSQL数据库中以10.000的大容量获取,然后传递到我的Lucene.NET包装类LuceneCorpus: public static void IndexPosts(LuceneCorpus luceneCorpus, IPostsRepository postsRepository, int chunkSize) { // omitted: this whol
public static void IndexPosts(LuceneCorpus luceneCorpus, IPostsRepository postsRepository, int chunkSize)
{
// omitted: this whole method is executed in a background worker to enable GUI feedback
// chunkSize is 10.000
int count = 0;
// totalSteps is ~10.000.000
int totalSteps = postsRepository.All.Count();
while (true)
{
var posts = postsRepository.All.Skip(count).Take(chunkSize).ToList();
if (posts.Count == 0)
break;
luceneCorpus.AddPosts(posts);
count += posts.Count;
}
luceneCorpus.OptimizeIndex();
}
我读到建议使用单个IndexWriter,而不是为每一批文档打开和关闭一个新的IndexWriter。因此,我的LuceneCorpus类如下所示:
public class LuceneCorpus
{
private Analyzer _analyzer;
private Directory _indexDir;
private IndexWriter _writer;
public LuceneCorpus(DirectoryInfo indexDirectory)
{
_indexDir = FSDirectory.Open(indexDirectory);
_analyzer = new StandardAnalyzer(Version.LUCENE_29);
_writer = new IndexWriter(_indexDir, _analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
_writer.SetRAMBufferSizeMB(128);
}
public void AddPosts(IEnumerable<Post> posts)
{
List<Document> docs = new List<Document>();
foreach (var post in posts)
{
var doc = new Document();
doc.Add(new Field("SimplifiedBody", post.SimplifiedBody, Field.Store.NO, Field.Index.ANALYZED));
_writer.AddDocument(doc);
}
_writer.Commit();
}
public void OptimizeIndex()
{
_writer.Optimize();
}
}
公共类LuceneCorpus
{
专用分析仪(u分析仪),;
私有目录_indexDir;
私人索引编写器;
公共LuceneCorpus(目录信息索引目录)
{
_indexDirectory=FSDirectory.Open(indexDirectory);
_analyzer=新标准分析仪(版本:LUCENE_29);
_writer=new IndexWriter(_indexDir,_analyzer,true,IndexWriter.MaxFieldLength.UNLIMITED);
_作者:SetRAMBufferSizeMB(128);
}
公共无效的AddPosts(IEnumerable posts)
{
列表单据=新建列表();
foreach(var post in post)
{
var doc=新文档();
新增单据(新增字段(“SimplifiedBody”,post.SimplifiedBody,Field.Store.NO,Field.Index.analysisted));
_writer.AddDocument(doc);
}
_writer.Commit();
}
公共索引()
{
_writer.Optimize();
}
}
现在,我的问题是,内存消耗一直在不断地被填满,直到我在IndexPosts方法中索引了大约700.000个文档之后,最终出现内存不足异常
据我所知,索引编写器应该在达到RAMBufferSize(128 MB)或调用Commit()时刷新。事实上,作者肯定会刷新,甚至会跟踪刷新,但内存仍在不断填满。作者是否以某种方式保留了对文档的引用,以便它们不会被垃圾收集,或者我在这里遗漏了什么
提前谢谢
Edit:我还尝试在AddPosts方法的范围内而不是在类范围内初始化writer、analyzer和indexDir,但这也不能防止OOM异常
我读到建议使用单个IndexWriter而不是
为每批文档打开和关闭一个新文档
一般来说,这可能是正确的,但您的特殊情况似乎需要另一种方法。您应该尝试每批使用一个writer。您的大内存需求迫使您使用效率低于最佳的解决方案。用内存换取速度,反之亦然——这很常见
我读到建议使用单个IndexWriter而不是
为每批文档打开和关闭一个新文档
一般来说,这可能是正确的,但您的特殊情况似乎需要另一种方法。您应该尝试每批使用一个writer。您的大内存需求迫使您使用效率低于最佳的解决方案。用内存换取速度,反之亦然——这很常见。试试最新和最棒的。它有一些内存泄漏修复
试试最新最棒的。它有一些内存泄漏修复
显然,Lucene没有导致内存泄漏,但我的PostsRepository的数据上下文是。我通过为每个“Take”迭代使用一个临时的非跟踪DC来解决这个问题
对不起,谢谢你 显然Lucene并没有导致内存泄漏,但我的PostsRepository的DataContext是。我通过为每个“Take”迭代使用一个临时的非跟踪DC来解决这个问题
对不起,谢谢你 一般来说,这很好,但即使我使用每批编写器的方法,问题也会出现。我用不同的批处理大小(500、1000或10000个文档)尝试了这种方法,但内存仍在不断地填满(!),直到我的内存用完。仅供参考:既然Lucene无关内存泄漏已经修复,我甚至可以使用单编写器方法!一般来说,这很好,但即使我使用每批编写器的方法,问题也会出现。我用不同的批处理大小(500、1000或10000个文档)尝试了这种方法,但内存仍在不断地填满(!),直到我的内存用完。仅供参考:既然Lucene无关内存泄漏已经修复,我甚至可以使用单编写器方法!